Fuzzer จะทำงานเป็นไคลเอ็นต์สำหรับบริการระยะไกลโดยการนำเข้าหรือเรียกใช้บริการผ่าน Stub ที่สร้างขึ้น
การใช้ 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);
});
เฟรมเวิร์กสำหรับ Fuzzing บริการ AIDL
ดังที่แสดงในตัวอย่างด้านบน fuzzService จะถูกเรียกใช้ใน Fuzzer และรับ IBinder (Service) และ dataProvider เป็น พารามิเตอร์อินพุต โดยจะเริ่มต้นออบเจ็กต์ Parcel แบบสุ่มโดยใช้ Data Provider และเรียกใช้เมธอด transact ในบริการระยะไกลโดยใช้ Parcel อินพุต จากนั้นรับการตอบกลับลงใน Parcel การตอบกลับ
สร้างและเรียกใช้ Fuzzer
ระบบจะสร้าง Fuzzer พร้อมความครอบคลุมโดยค่าเริ่มต้น
เราขอแนะนำให้ใช้ Sanitizer ต่อไปนี้เพื่อค้นหาปัญหาเกี่ยวกับหน่วยความจำ
Sanitizer hwaddress จะทำงานในสถาปัตยกรรม arm เท่านั้น
SANITIZE_HOST=address SANITIZE_TARGET=hwaddress
เมื่อเรียกใช้ด้วย libFuzzer คุณสามารถระบุ Corpus ซึ่งเป็นไดเรกทอรีในไฟล์ Android.bp และส่งไดเรกทอรีนี้ไปยัง Fuzzer ได้ นอกจากนี้ Fuzzer บางตัวยังระบุ
dictionary: ในไฟล์ Android.bp และคุณสามารถ
ส่งพจนานุกรมนี้ไปยัง libFuzzer ด้วย -dict path/to/dict ดูตัวเลือกเพิ่มเติมได้ใน
เอกสารประกอบอย่างเป็นทางการของ libFuzzer
หากต้องการเรียกใช้ Fuzzer ในอุปกรณ์ ให้เรียกใช้ adb sync data แล้วเรียกใช้
adb shell data/fuzz/arch/name/name
หากต้องการเรียกใช้ Fuzzer ในโฮสต์ ให้เรียกใช้
$ANDROID_HOST_OUT/fuzz/arch/name/name
แนะนำ Fuzzer สำหรับบริการใหม่หรือบริการที่มีอยู่
ระบบบิลด์จะตรวจสอบว่าบริการ Binder ของ AOSP ทุกรายการมีรายการ Fuzzer ใน
การผูก Fuzzer ของบริการหรือไม่
การทดสอบการผูก Fuzzer จะตรวจสอบว่าทุกบริการใน service_contexts มี Fuzzer หรือไม่ หากไม่พบ Fuzzer หรือข้อยกเว้นสำหรับบริการใหม่ ระบบจะแสดงข้อผิดพลาดในการบิลด์
คุณสามารถเขียน Fuzzer ของบริการ C++ อัตโนมัติได้โดยการเพิ่มรายการต่อไปนี้ (ระบบยังไม่รองรับ Fuzzer ของ Java และ Rust)
- รายการ
cc_fuzzในAndroid.bpเพื่อกำหนดโมดูล Fuzzer โมดูลcc_defaultservice_fuzzer_defaultsมีการขึ้นต่อกันที่จำเป็นสำหรับfuzzService - ควรเพิ่มการขึ้นต่อกันที่เฉพาะเจาะจงของบริการเป็นไลบรารีหรือเป็นแหล่งที่มา
- ไฟล์หลักที่สร้างบริการและเรียกใช้
fuzzService
ดูวิธีการโดยละเอียดเกี่ยวกับการใช้ cc_fuzz ได้ในเอกสารประกอบ
Fuzzing with libFuzzer
หากต้องการแก้ไขข้อผิดพลาดในการบิลด์ ให้อัปเดตการผูกด้วยชื่อบริการและ Fuzzer ใหม่ สำหรับบริการ Java หรือ Rust รายการ Fuzzer อาจว่างเปล่า