Le fuzzer se comporte comme un client pour le service distant en l'important/en l'invoquant via le stub généré :
Utilisation de 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;
}
Utilisation de l'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);
});
Cadre pour fuzzer les services AIDL
Comme le montre l'exemple ci-dessus, fuzzService est appelé dans le fuzzer et prend un IBinder (Service) et un dataProvider comme paramètres d'entrée. Il initialise d'abord un objet Parcel aléatoire à l'aide du fournisseur de données et appelle la méthode de transaction sur le service distant en utilisant le colis d'entrée, puis obtient la réponse dans un colis de réponse.
Construire et exécuter des fuzzers
Les fuzzers sont construits avec une couverture par défaut.
Les désinfectants suivants sont recommandés pour découvrir les problèmes de mémoire. Les désinfectants hwaddress
fonctionnent uniquement sur l'architecture arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Lors de l'exécution avec libFuzzer
, un corpus, qui est un répertoire, peut être spécifié dans le fichier Android.bp
, et vous pouvez transmettre ce répertoire au fuzzer. Certains fuzzers spécifient également un dictionary:
dans leur fichier Android.bp
, et vous pouvez le transmettre à libFuzzer avec -dict path/to/dict
. Pour plus d'options, consultez la documentation officielle de libFuzzer .
Pour exécuter des fuzzers sur l'appareil, exécutez adb sync data
, puis adb shell data/fuzz/ arch / name / name
. Pour exécuter des fuzzers sur l'hôte, exécutez $ANDROID_HOST_OUT/ fuzz / arch / name / name
.
Recommander des fuzzers pour les services nouveaux/existants
Le système de construction vérifie si chaque service de classeur AOSP a une entrée fuzzer dans les liaisons fuzzer du service . Le test de liaison Fuzzer vérifie que chaque service dans service_contexts
possède un fuzzer. Si un fuzzer/exception n'est pas trouvé pour un nouveau service, il y a une erreur de construction.
Un fuzzer de service C++ automatique peut être écrit en ajoutant ce qui suit (les fuzzers Java et Rust ne sont pas encore pris en charge) :
- Une entrée
cc_fuzz
dansAndroid.bp
pour définir le module fuzzer. Le modulecc_default
service_fuzzer_defaults
a les dépendances requises pourfuzzService
. - Les dépendances spécifiques au service doivent être ajoutées en tant que bibliothèque ou en tant que sources.
- Un fichier principal qui construit votre service et appelle
fuzzService
Pour des instructions détaillées sur l'utilisation cc_fuzz
, consultez la documentation Fuzzing avec libFuzzer . Pour résoudre l'erreur de build, mettez à jour les liaisons avec les nouveaux noms de service et de fuzzer. Pour les services Java/Rust, la liste des fuzzers peut être vide.