模糊器透過產生的存根導入/呼叫遠端服務,充當遠端服務的客戶端:
使用 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 服務的框架
如上例所示,fuzzer 中呼叫了fuzzService ,並接受 IBinder(Service)和 dataProvider 作為輸入參數。它首先使用資料提供者初始化一個隨機 Parcel 對象,並使用輸入的 Parcel 呼叫遠端服務上的 transact 方法,最後將回應取得到回應 Parcel 中。
建置並運行模糊器
預設情況下,模糊器是透過覆蓋率建構的。
建議使用以下清理程序來發現記憶體問題。 hwaddress
sanitizers 僅在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 綁定器服務在服務模糊器綁定中是否有模糊器條目。模糊器綁定測試檢查service_contexts
中的每個服務是否都有模糊器。如果未找到新服務的模糊器/異常,則存在建置錯誤。
可以透過新增以下內容來編寫自動 C++ 服務模糊器(尚不支援 Java 和 Rust 模糊器):
-
Android.bp
中的cc_fuzz
條目用於定義模糊器模組。cc_default
模組service_fuzzer_defaults
具有fuzzService
所需的依賴項。 - 特定於服務的依賴項應作為庫或來源添加。
- 建置服務並呼叫
fuzzService
的主文件
有關使用cc_fuzz
詳細說明,請參閱使用 libFuzzer 進行模糊測試文件。若要解決建置錯誤,請使用新的服務和模糊器名稱更新綁定。對於 Java/Rust 服務,模糊器清單可以為空。