فازر با وارد کردن یا فراخوانی سرویس از راه دور از طریق stub تولید شده، به عنوان یک کلاینت برای آن رفتار میکند:
استفاده از 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;
}
استفاده از API Rust:
#![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 را با استفاده از ارائه دهنده داده مقداردهی اولیه میکند و با استفاده از بسته ورودی، متد transact را روی سرویس راه دور فراخوانی میکند و در نهایت پاسخ را در یک بسته پاسخ دریافت میکند.
ساخت و اجرای فازرها
فازرها به طور پیشفرض با پوشش ساخته میشوند.
برای کشف مشکلات حافظه، ضدعفونیکنندههای زیر توصیه میشوند. ضدعفونیکنندههای hwaddress فقط روی معماری arm اجرا میشوند:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
هنگام اجرا با libFuzzer ، یک مجموعه کد (corpus) که یک دایرکتوری است، ممکن است در فایل Android.bp مشخص شود و شما میتوانید این دایرکتوری را به fuzzer ارسال کنید. برخی از fuzzerها همچنین یک 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 binder دارای ورودی فازر در service fuzzer bindings است یا خیر. تست اتصال فازر بررسی میکند که آیا هر سرویس در service_contexts دارای فازر است یا خیر. اگر فازر یا استثنا برای یک سرویس جدید یافت نشد، خطای ساخت وجود دارد.
یک فازر سرویس خودکار C++ را میتوان با اضافه کردن موارد زیر نوشت (فازرهای جاوا و Rust هنوز پشتیبانی نمیشوند):
- یک ورودی
cc_fuzzدرAndroid.bpبرای تعریف ماژول fuzzer. ماژولcc_defaultservice_fuzzer_defaultsدارای وابستگیهای مورد نیاز برایfuzzServiceاست. - وابستگیهای مختص سرویس باید به صورت کتابخانه یا منبع اضافه شوند.
- یک فایل اصلی که سرویس شما را میسازد و
fuzzServiceرا فراخوانی میکند.
برای دستورالعملهای دقیق در مورد استفاده از cc_fuzz ، به مستندات Fuzzing with libFuzzer مراجعه کنید. برای رفع خطای ساخت، اتصالات را با نامهای جدید سرویس و fuzzer بهروزرسانی کنید. برای سرویسهای Java یا Rust، لیست fuzzer میتواند خالی باشد.