AIDL Fuzzing

fuzzer به عنوان یک مشتری برای سرویس راه دور با وارد کردن / فراخوانی آن از طریق خرد تولید شده رفتار می کند:

استفاده از 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 در fuzzer فراخوانی می شود و یک IBinder (سرویس) و dataProvider را به عنوان پارامترهای ورودی می گیرد. ابتدا یک شی بسته تصادفی را با استفاده از ارائه‌دهنده داده مقداردهی می‌کند و با استفاده از بسته ورودی، متد تراکنش را در سرویس راه دور فراخوانی می‌کند و در نهایت پاسخ را در یک بسته پاسخ دریافت می‌کند.

fuzzer ها را بسازید و اجرا کنید

Fuzzers به ​​طور پیش فرض با پوشش ساخته شده است.

برای کشف مشکلات حافظه، ضدعفونی‌کننده‌های زیر توصیه می‌شوند. ضدعفونی‌کننده‌های hwaddress فقط با معماری arm کار می‌کنند:

SANITIZE_HOST=address SANITIZE_TARGET=hwaddress

هنگام اجرا با libFuzzer ، ممکن است یک مجموعه، که یک دایرکتوری است، در فایل Android.bp مشخص شود، و می توانید این فهرست را به fuzzer ارسال کنید. برخی از fuzzer ها همچنین یک dictionary: در فایل Android.bp خود مشخص می کنند، و می توانید آن را با -dict path/to/dict به libFuzzer ارسال کنید. برای گزینه‌های بیشتر، به مستندات رسمی libFuzzer مراجعه کنید.

برای اجرای fuzzer ها روی دستگاه، adb sync data و سپس adb shell data/fuzz/ arch / name / name را اجرا کنید. برای اجرای fuzzer ها در میزبان، $ANDROID_HOST_OUT/ fuzz / arch / name / name را اجرا کنید.

سیستم ساخت بررسی می کند که آیا هر سرویس بایندر AOSP یک ورودی fuzzer در اتصالات فازر سرویس دارد یا خیر. تست اتصال Fuzzer بررسی می کند که هر سرویس در service_contexts دارای یک fuzzer باشد. اگر یک fuzzer/exception برای یک سرویس جدید پیدا نشد، یک خطای ساخت وجود دارد.

یک fuzzer خودکار سرویس ++C را می‌توان با افزودن موارد زیر نوشت (جاوا و Rust fuzzer هنوز پشتیبانی نمی‌شوند):

  • یک ورودی cc_fuzz در Android.bp برای تعریف ماژول fuzzer. ماژول cc_default service_fuzzer_defaults وابستگی های مورد نیاز برای fuzzService دارد.
  • وابستگی های خاص سرویس باید به عنوان یک کتابخانه یا به عنوان منبع اضافه شوند.
  • یک فایل اصلی که سرویس شما را می سازد و fuzzService را فراخوانی می کند

برای دستورالعمل های دقیق در مورد استفاده از cc_fuzz ، به مستندات Fuzzing with libFuzzer مراجعه کنید. برای رفع خطای ساخت، اتصالات را با نام سرویس جدید و fuzzer به روز کنید. برای سرویس های Java/Rust، لیست fuzzer می تواند خالی باشد.