Fuzzer działa jak klient usługi zdalnej, importując ją lub wywołując za pomocą wygenerowanego zastępnika:
Korzystanie z interfejsu 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;
}
Korzystanie z Rust API:
#![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 do testowania podatności usług AIDL
Jak widać w przykładzie powyżej, metoda fuzzService jest wywoływana w fuzzerze i otrzymuje jako parametry wejściowe interfejs IBinder (Service) oraz obiekt dataProvider. Najpierw inicjuje losowy obiekt Parcel za pomocą dostawcy danych, a następnie wywołuje metodę transakcji w usłudze zdalnej, używając obiektu inputParcel, i w końcu uzyskuje odpowiedź w obiektie replyParcel.
Tworzenie i uruchamianie narzędzi do testowania podatności na błędy
Domyślnie fuzzery są tworzone z uwzględnieniem pokrycia.
Aby wykryć problemy z pamięcią, zalecamy użycie tych narzędzi do sprawdzania kodu.
hwaddress
dezynfekujące działają tylko w architekturze arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Podczas uruchamiania narzędzia libFuzzer
w pliku Android.bp
można określić korpus, który jest katalogiem. Ten katalog można przekazać fuzzerowi. Niektóre fuzzery podają też w pliku Android.bp
parametr dictionary:
, który możesz przekazać do libFuzzer za pomocą parametru -dict path/to/dict
. Więcej opcji znajdziesz w oficjalnej dokumentacji libFuzzer.
Aby uruchomić fuzzer na urządzeniu, uruchom adb sync data
, a potem adb shell data/fuzz/arch/name/name
.
Aby uruchomić fuzzer na hoście, uruchom $ANDROID_HOST_OUT/fuzz/arch/name/name
.
Polecanie fuzzerów w przypadku nowych lub istniejących usług
System kompilacji sprawdza, czy każda usługa bindera AOSP ma wpis fuzzera w powiązaniach fuzzera usługi.
Test wiązania fuzzera sprawdza, czy każda usługa w service_contexts
ma fuzzera. Jeśli nie uda się znaleźć fuzzera ani wyjątku dla nowej usługi, wystąpi błąd kompilacji.
Automatyczny fuzzer usługi w C++ można napisać, dodając te elementy (fuzzery w Javie i Rust nie są jeszcze obsługiwane):
- W pliku
Android.bp
wpiscc_fuzz
, który definiuje moduł fuzzer. Modułcc_default
service_fuzzer_defaults
ma zależności wymagane dofuzzService
. - Zależność związaną z konkretną usługą należy dodać jako bibliotekę lub źródło.
- Plik główny, który tworzy usługę i wywołuje
fuzzService
Szczegółowe instrukcje dotyczące korzystania z cc_fuzz
znajdziesz w dokumentacji Fuzzing za pomocą libFuzzer. Aby rozwiązać problem z kompilacją, zaktualizuj powiązania, podając nowe nazwy usługi i fuzzera. W przypadku usług w Javie lub Rust lista fuzzera może być pusta.