El fuzzer se comporta como un cliente para el servicio remoto importándolo/invocándolo a través del código auxiliar generado:
Usando la API de 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;
}
Usando la API de 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);
});
Marco para difuminar los servicios AIDL
Como se muestra en el ejemplo anterior, se llama a fuzzService en el fuzzer y toma un IBinder (servicio) y un proveedor de datos como parámetros de entrada. Primero inicializa un objeto Parcel aleatorio utilizando el proveedor de datos y llama al método de transacción en el servicio remoto utilizando el paquete de entrada y, finalmente, obtiene la respuesta en un paquete de respuesta.
Construir y ejecutar fuzzers
Los fuzzers están construidos con cobertura de forma predeterminada.
Se recomiendan los siguientes desinfectantes para descubrir problemas de memoria. Los desinfectantes hwaddress
solo funcionan en la arquitectura arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
Cuando se ejecuta con libFuzzer
, se puede especificar un corpus, que es un directorio, en el archivo Android.bp
, y usted puede pasar este directorio al fuzzer. Algunos fuzzers también especifican un dictionary:
en su archivo Android.bp
, y puedes pasarlo a libFuzzer con -dict path/to/dict
. Para obtener más opciones, consulte la documentación oficial de libFuzzer .
Para ejecutar fuzzers en el dispositivo, ejecute adb sync data
y luego adb shell data/fuzz/ arch / name / name
. Para ejecutar fuzzers en el host, ejecute $ANDROID_HOST_OUT/ fuzz / arch / name / name
.
Recomendar fuzzers para servicios nuevos/existentes
El sistema de compilación comprueba si cada servicio de carpeta AOSP tiene una entrada de fuzzer en los enlaces de fuzzer de servicio . La prueba de enlace de Fuzzer comprueba que cada servicio en service_contexts
tenga un fuzzer. Si no se encuentra un fuzzer/excepción para un nuevo servicio, hay un error de compilación.
Se puede escribir un fuzzer de servicio C++ automático agregando lo siguiente (los fuzzers de Java y Rust aún no son compatibles):
- Una entrada
cc_fuzz
enAndroid.bp
para definir el módulo fuzzer. El módulocc_default
service_fuzzer_defaults
tiene dependencias necesarias parafuzzService
. - Las dependencias específicas del servicio deben agregarse como biblioteca o como fuentes.
- Un archivo principal que construye su servicio y llama
fuzzService
Para obtener instrucciones detalladas sobre el uso cc_fuzz
, consulte la documentación Fuzzing con libFuzzer . Para resolver el error de compilación, actualice los enlaces con los nuevos nombres de servicio y fuzzer. Para los servicios Java/Rust, la lista de fuzzer puede estar vacía.