«فازر» با وارد کردن یا فراخواندن سرویس از دور ازطریق میانای تولیدشده، بهعنوان کارخواه سرویس از دور عمل میکند:
استفاده از 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 در fuzzzer فراخوانده میشود و IBinder (سرویس) و dataProvider را بهعنوان پارامترهای ورودی میگیرد. ابتدا بااستفاده از ارائهدهنده داده یک شیء Parcel تصادفی را مقداردهی اولیه میکند و بااستفاده از بسته ورودی، روش transact را در سرویس راه دور فرا میخواند و درنهایت پاسخ را در بسته پاسخ دریافت میکند.
ساختن و اجرای fuzzers
بهطور پیشفرض، fuzzers با پوشش ساخته میشوند.
برای کشف مشکلات حافظه، پاککنندههای زیر توصیه میشود.
hwaddress پاککننده فقط در معماری arm اجرا میشود:
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
هنگام اجرا با libFuzzer، پیکرهای که یک دایرکتوری است ممکن است در فایل Android.bp مشخص شود و میتوانید این دایرکتوری را به فازر منتقل کنید. برخیاز
فازرها همچنین dictionary: را در فایل Android.bp خود مشخص میکنند و میتوانید
آن را با -dict path/to/dict به libFuzzer ارسال کنید. برای
گزینههای بیشتر،
اسناد رسمی libFuzzer را ببینید.
برای اجرای fuzzers در دستگاه، adb sync data و سپس
adb shell data/fuzz/arch/name/name را اجرا کنید.
برای اجرای fuzzers در میزبان،
$ANDROID_HOST_OUT/fuzz/arch/name/name را اجرا کنید.
توصیه کردن fuzzers برای سرویسهای جدید یا موجود
سیستم ساخت بررسی میکند که آیا هر سرویس متصلکننده AOSP دارای ورودی فازر در
اتصالهای فازر سرویس است یا نه.
آزمایش پیوند Fuzzer بررسی میکند که هر سرویس در service_contexts
یک fuzzer داشته باشد. اگر برای سرویس جدیدی فازر یا استثنایی پیدا نشود، خطای ساخت وجود دارد.
با افزودن موارد زیر میتوان یک سرویس C++ fuzzing خودکار نوشت (از fuzzing جاوا و Rust هنوز پشتیبانی نمیشود):
- یک ورودی
cc_fuzzدرAndroid.bpبرای تعریف کردن واحد فازر. واحدcc_defaultservice_fuzzer_defaultsوابستگیهایی دارد که برایfuzzServiceلازم است. - وابستگیهای مختص سرویس باید بهعنوان کتابخانه یا بهعنوان منبع اضافه شوند.
- فایل اصلی که سرویس شما را میسازد و
fuzzServiceرا فرا میخواند
برای دستورالعملهای دقیق درباره استفاده از cc_fuzz، به سند
Fuzzing with libFuzzer
مراجعه کنید. برای رفع خطای ساخت، پیوندها را با نامهای سرویس و
فازر جدید بهروز کنید. برای سرویسهای Java یا Rust، فهرست فازر میتواند خالی باشد.