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);
});
Usando la API de Java:
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import randomparcel.FuzzBinder;
public class ServiceFuzzer {
static {
// Initialize fuzzService and JNI dependencies
FuzzBinder.init();
}
public static void fuzzerTestOneInput(FuzzedDataProvider data) {
TestService service = new TestService();
FuzzBinder.fuzzService(service, data.consumeRemainingAsBytes());
}
}
Para la configuración de compilación, consulte Java Binder Service Fuzzer .
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.
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.