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