Fuzzer zachowuje się jak klient usługi zdalnej, importując/wywołując ją poprzez wygenerowany kod pośredniczący:
Korzystanie z 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;
}
Korzystanie z API Rusta:
#![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 fuzowania usług AIDL
Jak pokazano w powyższym przykładzie, fuzzService jest wywoływany w fuzzerze i pobiera IBinder (usługę) i dataProvider jako parametry wejściowe. Najpierw inicjuje losowy obiekt Parcel przy użyciu dostawcy danych i wywołuje metodę transakcji w usłudze zdalnej przy użyciu paczki wejściowej, a na koniec otrzymuje odpowiedź w paczce zwrotnej.
Twórz i uruchamiaj fuzzery
Fuzzery są domyślnie zbudowane z pokryciem.
W celu wykrycia problemów z pamięcią zalecane są następujące środki odkażające. środki dezynfekujące hwaddress
działają tylko na architekturze arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Podczas uruchamiania z libFuzzer
korpus będący katalogiem może zostać określony w pliku Android.bp
i można przekazać ten katalog do fuzzera. Niektórzy fuzzerzy określają także dictionary:
w swoim pliku Android.bp
i możesz przekazać go do libFuzzer za pomocą -dict path/to/dict
. Więcej opcji znajdziesz w oficjalnej dokumentacji libFuzzer .
Aby uruchomić fuzzery na urządzeniu, uruchom adb sync data
, a następnie adb shell data/fuzz/ arch / name / name
. Aby uruchomić fuzzery na hoście, uruchom $ANDROID_HOST_OUT/ fuzz / arch / name / name
.
Polecanie fuzzerów dla nowych/istniejących usług
System kompilacji sprawdza, czy każda usługa segregatora AOSP ma wpis fuzzera w powiązaniach usługi fuzzer . Test powiązania Fuzzera sprawdza, czy każda usługa w service_contexts
ma fuzzer. Jeśli dla nowej usługi nie zostanie znaleziony fuzzer/wyjątek, oznacza to błąd kompilacji.
Automatyczny fuzzer usługi C++ można napisać, dodając następujące elementy (fuzzery Java i Rust nie są jeszcze obsługiwane):
- Wpis
cc_fuzz
wAndroid.bp
definiujący moduł fuzzera. Modułcc_default
service_fuzzer_defaults
ma zależności wymagane dlafuzzService
. - Zależności specyficzne dla usługi należy dodać jako bibliotekę lub jako źródła.
- Główny plik, który konstruuje Twoją usługę i wywołuje
fuzzService
Szczegółowe instrukcje dotyczące używania cc_fuzz
można znaleźć w dokumentacji Fuzzing with libFuzzer . Aby rozwiązać błąd kompilacji, zaktualizuj powiązania, dodając nowe nazwy usług i fuzzerów. W przypadku usług Java/Rust lista fuzzerów może być pusta.