透過匯入或叫用產生的虛設常式,模糊測試器會充當遠端服務的用戶端:
使用 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;
}
使用 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);
});
模糊測試 AIDL 服務的架構
如上例所示,fuzzService 會在模糊測試器中呼叫,並將 IBinder (服務) 和 dataProvider 做為輸入參數。首先,它會使用資料供應器初始化隨機 Parcel 物件,並使用輸入 Parcel 呼叫遠端服務的 transact 方法,最後將回覆內容放入回覆 Parcel。
建構及執行模糊測試器
根據預設,模糊測試器會使用涵蓋範圍建構。
建議使用下列清除工具來找出記憶體問題。
hwaddress 清潔器僅在 arm 架構上執行:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
使用 libFuzzer 執行時,可以在 Android.bp 檔案中指定語料庫 (目錄),並將這個目錄傳遞至模糊測試器。部分模糊測試器也會在 Android.bp 檔案中指定 dictionary:,您可以使用 -dict path/to/dict 將此檔案傳遞至 libFuzzer。如需更多選項,請參閱 libFuzzer 官方說明文件。
如要在裝置上執行模糊測試器,請執行 adb sync data,然後執行 adb shell data/fuzz/arch/name/name。
如要在主機上執行模糊測試器,請執行 $ANDROID_HOST_OUT/fuzz/arch/name/name。
為新服務或現有服務推薦模糊測試器
建構系統會檢查每個 AOSP 繫結器服務在服務模糊測試繫結中是否都有模糊測試器項目。Fuzzer 繫結測試會檢查 service_contexts 中的每個服務是否都有模糊測試工具。如果找不到新服務的模糊測試器或例外狀況,就會發生建構錯誤。
如要編寫自動 C++ 服務模糊測試器,請新增下列項目 (目前不支援 Java 和 Rust 模糊測試器):
Android.bp中的cc_fuzz項目,用於定義模糊測試器模組。cc_default模組service_fuzzer_defaults具有fuzzService所需的依附元件。- 應以程式庫或來源的形式新增服務專屬依附元件。
- 建構服務並呼叫
fuzzService的主要檔案
如需使用 cc_fuzz 的詳細操作說明,請參閱「使用 libFuzzer 進行模糊測試」說明文件。如要解決建構錯誤,請使用新的服務和模糊測試器名稱更新繫結。如果是 Java 或 Rust 服務,模糊測試器清單可以空白。