ה-fuzzer מתנהג כלקוח בשביל השירות המרוחק על ידי ייבוא או הפעלה שלו דרך ה-stub שנוצר:
באמצעות 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;
}
באמצעות 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);
});
מסגרת של שירותי fuzzing AIDL
כמו שאפשר לראות בדוגמה שלמעלה, ל-fuzzService יש קריאה ב-fuzzer והוא מקבל את IBinder (Service) ואת dataProvider כפרמטרים של קלט. קודם כול, מאתחלים אובייקט Parcel אקראי באמצעות ספק הנתונים, מפעילים את ה-method לביצוע טרנזקציה בשירות המרוחק באמצעות חבילת הקלט, ולבסוף מקבלים את התשובה לחבילת תשובה.
בנייה והפעלה של fuzzers
Fuzzers נוצרים עם כיסוי כברירת מחדל.
מומלץ להשתמש בחומרי החיטוי הבאים כדי לזהות בעיות בזיכרון.
חומרי חיטוי של hwaddress
פועלים רק בארכיטקטורה arm
:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
כשמריצים עם libFuzzer
, ניתן לציין קורפוס, שהוא ספרייה, בקובץ Android.bp
, ואפשר להעביר את הספרייה הזו ל-fuzzer. חלק מקובצי ה-fuzzer גם מציינים dictionary:
בקובץ Android.bp
, ואפשר להעביר אותו ל-libFuzzer באמצעות -dict path/to/dict
. לאפשרויות נוספות, עיינו במסמכי התיעוד הרשמיים של libFuzzer.
כדי להריץ fuzzers במכשיר, מריצים את adb sync data
ואז את adb shell data/fuzz/arch/name/name
.
כדי להריץ fuzzers במארח, מריצים את $ANDROID_HOST_OUT/fuzz/arch/name/name
.
המלצה על fuzzers לשירותים חדשים או קיימים
מערכת ה-build בודקת אם לכל שירות binder של AOSP יש רשומת fuzzer בקישורי fuzzer של שירותים.
בבדיקת הקישור של Fuzzer, המערכת מוודאת שלכל שירות ב-service_contexts
יש fuzzer. אם לא נמצאו fuzzer או חריגים בשירות חדש, נחשבת שגיאה ב-build.
אפשר לכתוב fuzzer אוטומטי של שירות C++ על ידי הוספת הקוד הבא (Java ו-Rust fuzzers עדיין לא נתמכים):
- רשומת
cc_fuzz
ב-Android.bp
להגדרת מודול fuzzer. במודולcc_default
service_fuzzer_defaults
יש יחסי תלות שנדרשים בשבילfuzzService
. - יחסי תלות ספציפיים לשירות יש להוסיף כספרייה או כמקורות.
- קובץ ראשי שיוצר את השירות ומבצע קריאה ל-
fuzzService
להוראות מפורטות על השימוש ב-cc_fuzz
, ראו Fuzzing with libFuzzer. כדי לפתור שגיאות build, מעדכנים את הקישורים לשירות החדש ולשמות של fuzzer. לשירותי Java או Rust, רשימת ה-fuzzer יכולה להיות ריקה.