Le fuzzer se comporte comme un client pour le service distant en l'important ou en l'appelant via le bouchon généré:
Avec 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;
}
Avec 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);
});
Framework pour échapper les services AIDL
Comme indiqué dans l'exemple ci-dessus, fuzzService est appelé dans le fuzzer et accepte un IBinder (Service) et un fournisseur de données comme paramètres d'entrée. Il initialise d'abord un objet Parcel aléatoire à l'aide du fournisseur de données, appelle la méthode "transactions" sur le service distant à l'aide du parc d'entrée, puis récupère la réponse dans un paquet "Répondre".
Créer et exécuter des fuzzers
Les fuzzers sont conçus avec une couverture par défaut.
Les désinfectants suivants sont recommandés pour détecter les problèmes de mémoire.
Les désinfectants hwaddress
ne s'exécutent que 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
. Vous pouvez transmettre ce répertoire au fuzzer. Certains fuzzers spécifient également un dictionary:
dans leur fichier Android.bp
, que vous pouvez 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 des services nouveaux ou existants
Le système de compilation vérifie si chaque service de liaison AOSP possède une entrée de fuzzer dans les liaisons de fuzzer de service.
Le test de liaison de fuzzer vérifie que chaque service de service_contexts
dispose d'un fuzzer. Si un fuzzer ou une exception est introuvable pour un nouveau service, une erreur de compilation se produit.
Vous pouvez écrire un fuzzer automatique de service C++ en ajoutant ce qui suit (les fuzzers Java et Rust ne sont pas encore compatibles):
- Une entrée
cc_fuzz
dansAndroid.bp
pour définir le module de fuzzer. Le modulecc_default
service_fuzzer_defaults
comporte les dépendances requises pourfuzzService
. - Les dépendances spécifiques aux services doivent être ajoutées en tant que bibliothèque ou en tant que sources.
- Un fichier principal qui crée votre service et appelle
fuzzService
Pour obtenir des instructions détaillées sur l'utilisation de cc_fuzz
, consultez la documentation Fuzzing with libFuzzer. Pour résoudre l'erreur de compilation, mettez à jour les liaisons avec les nouveaux noms de service et de fuzzer. Pour les services Java ou Rust, la liste des fuzzers peut être vide.