Il fuzzer si comporta come un client per il servizio remoto importandolo o invocandolo tramite lo stub generato:
Utilizzo dell'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 eseguire fuzz dei servizi AIDL
Come mostrato nell'esempio precedente, fuzzService viene chiamato nel fuzzer e accetta un IBinder (Service) e dataProvider come parametri di input. Inizializza innanzitutto un oggetto Parcel casuale utilizzando i dati provider e chiamare il metodo di transazione sul servizio remoto utilizzando e ricevere la risposta nel pacchetto di risposta.
Crea ed esegui fuzzer
I fuzzer vengono creati con la copertura per impostazione predefinita.
Per rilevare i problemi di memoria, consigliamo i seguenti disinfettanti.
hwaddress
di sanitizer vengono eseguiti solo sull'architettura arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Quando viene eseguito con libFuzzer
, è possibile specificare un corpus, ovvero una directory
nel file Android.bp
e puoi passare questa directory al fuzzer. Alcuni
fuzzer specificano anche un dictionary:
nel file Android.bp
e puoi
trasmetterlo a libFuzzer con -dict path/to/dict
. Per
altre opzioni, consulta le
documentazione ufficiale di libFuzzer.
Per eseguire i fuzzer sul dispositivo, esegui adb sync data
e poi
adb shell data/fuzz/arch/name/name
.
Per eseguire i fuzzer sull'host, esegui
$ANDROID_HOST_OUT/fuzz/arch/name/name
.
Consigliare fuzzer per servizi nuovi o esistenti
Il sistema di compilazione verifica se ogni servizio binder AOSP ha una voce fuzzer in
associazioni di servizi fuzzer.
Il test di associazione del fuzzer verifica che ogni servizio in service_contexts
abbia un
fuzzer. Se non viene trovato un fuzzer o un'eccezione per un nuovo servizio, si è verificato un errore di compilazione.
È possibile scrivere un fuzzer automatico per i servizi C++ aggiungendo quanto segue (i fuzzer Java e Rust non sono ancora supportati):
- Una voce
cc_fuzz
inAndroid.bp
per definire il modulo del fuzzer. Il modulocc_default
service_fuzzer_defaults
ha le dipendenze necessarie perfuzzService
. - Le dipendenze specifiche del servizio devono essere aggiunte come librerie o come origini.
- Un file principale che crea il servizio e chiama
fuzzService
Per istruzioni dettagliate sull'utilizzo di cc_fuzz
, consulta la documentazione relativa al fuzzing con libFuzzer. Per risolvere l'errore di compilazione, aggiorna le associazioni con i nuovi nomi del servizio e del fuzzer. Per i servizi Java o Rust, l'elenco fuzzer può essere vuoto.