ファザーは、生成されたスタブを介してリモート サービスをインポートまたは呼び出すことにより、リモート サービス用のクライアントとして機能します。
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(Service)と dataProvider を入力パラメータとして受け取ります。まず、データ プロバイダを使用して、ランダムな Parcel オブジェクトを初期化し、入力 Parcel を使用してリモート サービスで transact メソッドを呼び出して、最後に応答 Parcel にレスポンスを取得します。
ファザーをビルドして実行する
ファザーは、デフォルトでカバレッジ付きでビルドされます。
以下のサニタイザーを使用してメモリの問題を特定することを推奨します。hwaddress
サニタイザーは、arm
アーキテクチャでのみ実行されます。
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
libFuzzer
で実行する場合、コーパス(ディレクトリ)を Android.bp
ファイルで指定して、このディレクトリをファザーに渡すことができます。一部のファザーは dictionary:
も Android.bp
ファイルで指定します。これは、-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 サービスの場合、ファザーリストは空にできます。