O fuzzer se comporta como um cliente para o serviço remoto importando/invocando-o através do stub gerado:
Usando 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;
}
Usando 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);
});
Usando API 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 configuração de compilação, consulte Java Binder Service Fuzzer .
Estrutura para difundir serviços AIDL
Conforme mostrado no exemplo acima, fuzzService é chamado no fuzzer e recebe um IBinder (Service) e dataProvider como parâmetros de entrada. Ele primeiro inicializa um objeto Parcel aleatório usando o provedor de dados e chama o método transact no serviço remoto usando o pacote de entrada e, finalmente, obtém a resposta em um pacote de resposta.
Recomendando fuzzers para serviços novos/existentes
O sistema de compilação verifica se cada serviço de binder AOSP possui uma entrada de fuzzer em service fuzzer bindings . O teste de ligação do Fuzzer verifica se cada serviço em service_contexts
possui um fuzzer. Se um fuzzer/exceção não for encontrado para um novo serviço, há um erro de compilação.
Um fuzzer de serviço C++ automático pode ser escrito adicionando o seguinte (fuzzers Java e Rust ainda não são suportados):
- Uma entrada
cc_fuzz
emAndroid.bp
para definir o módulo fuzzer. O módulocc_default
service_fuzzer_defaults
possui dependências necessárias parafuzzService
. - As dependências específicas do serviço devem ser adicionadas como uma biblioteca ou como fontes.
- Um arquivo principal que constrói seu serviço e chama
fuzzService
Para obter instruções detalhadas sobre como usar cc_fuzz
, consulte a documentação Fuzzing com libFuzzer . Para resolver o erro de construção, atualize as ligações com os novos nomes de serviço e fuzzer. Para serviços Java/Rust, a lista de fuzzers pode estar vazia.