ตัวล้าง HWAddress

Android NDK รองรับ HWAddress Sanitizer หรือที่เรียกว่า HWASan ตั้งแต่ NDK r21 และ Android 10 (API ระดับ 29) เป็นต้นไป HWASan ใช้ได้เฉพาะในอุปกรณ์ Arm แบบ 64 บิต เท่านั้น

HWASan เป็นเครื่องมือตรวจหาข้อผิดพลาดด้านหน่วยความจําที่คล้ายกับ ASan เมื่อเทียบกับ ASan แบบคลาสสิก HWASan มีคุณสมบัติดังนี้

  • ค่าใช้จ่าย CPU ที่คล้ายกัน (~2 เท่า)
  • ค่าใช้จ่ายเพิ่มเติมด้านขนาดโค้ดที่คล้ายกัน (40-50%)
  • ค่าใช้จ่ายด้าน RAM น้อยลงมาก (10% - 35%)

HWASan ตรวจหาข้อบกพร่องชุดเดียวกับ ASan ดังนี้

  • Stack และ Heap Buffer Overflow หรือ Underflow
  • การใช้ฮีปหลังจากปล่อย
  • การใช้สแต็กนอกขอบเขต
  • ฟรี 2 เท่าหรือฟรีแบบไม่จำกัด

นอกจากนี้ HWASan ยังตรวจหาข้อผิดพลาดต่อไปนี้ได้ด้วย

  • การใช้กองซ้อนหลังจากกลับมา

แอปตัวอย่าง

แอปตัวอย่าง แสดงวิธีกําหนดค่าตัวแปรบิลด์สําหรับ hwasan

สร้าง

หากต้องการสร้างโค้ดเนทีฟ (JNI) ของแอปด้วย HWAddress Sanitizer ให้ทำดังนี้

ndk-build

ในไฟล์ Application.mk

APP_STL := c++_shared # Or system, or none, but not c++_static.
APP_CFLAGS := -fsanitize=hwaddress -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=hwaddress

CMake (Gradle Groovy)

ในไฟล์ build.gradle ของโมดูล ให้ทำดังนี้

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments "-DANDROID_STL=c++_shared"
            }
        }
    }
}

สำหรับแต่ละเป้าหมายใน CMakeLists.txt ให้ทำดังนี้

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

เมื่อใช้ NDK 27 ขึ้นไป คุณยังใช้รายการต่อไปนี้ใน build.gradle ได้โดยไม่ต้องเปลี่ยน CMakeLists.txt

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

วิธีนี้จะใช้ไม่ได้เมื่อใช้ ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false

CMake (Gradle Kotlin)

ในไฟล์ build.gradle ของโมดูล ให้ทำดังนี้

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                # Can also use system or none as ANDROID_STL, but not c++_static.
                arguments += "-DANDROID_STL=c++_shared"
            }
        }
    }
}

สำหรับแต่ละเป้าหมายใน CMakeLists.txt ให้ทำดังนี้

target_compile_options(${TARGET} PUBLIC -fsanitize=hwaddress -fno-omit-frame-pointer)
target_link_options(${TARGET} PUBLIC -fsanitize=hwaddress)

เมื่อใช้ NDK 27 ขึ้นไป คุณยังใช้รายการต่อไปนี้ใน build.gradle ได้โดยไม่ต้องเปลี่ยน CMakeLists.txt

android {
    defaultConfig {
        externalNativeBuild {
            cmake {
                arguments += "-DANDROID_SANITIZE=hwaddress"
            }
        }
    }
}

วิธีนี้จะใช้ไม่ได้เมื่อใช้ ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false

Android 14 ขึ้นไป: เพิ่ม wrap.sh

หากใช้ Android 14 ขึ้นไป คุณสามารถใช้สคริปต์ wrap.sh เพื่อเรียกใช้แอปที่แก้ไขข้อบกพร่องได้ในอุปกรณ์ที่ใช้ Android คุณข้ามขั้นตอนนี้ได้หากเลือกทำตามขั้นตอน ในวิธีการตั้งค่า

ทำตามวิธีการเพื่อแพ็กเกจสคริปต์ wrap.sh เพื่อเพิ่ม สคริปต์ wrap.sh ต่อไปนี้สำหรับ arm64-v8a

#!/system/bin/sh
LD_HWASAN=1 exec "$@"

เรียกใช้

หากใช้ Android เวอร์ชันเก่ากว่า 14 หรือไม่ได้เพิ่มสคริปต์ wrap.sh ให้ทำตามวิธีการตั้งค่าก่อนเรียกใช้แอป

เรียกใช้แอปตามปกติ เมื่อตรวจพบข้อผิดพลาดเกี่ยวกับหน่วยความจำ แอปจะขัดข้องพร้อม SIGABRT และพิมพ์ข้อความโดยละเอียดไปยัง Logcat คุณดูสำเนาข้อความได้ในไฟล์ที่อยู่ใน /data/tombstones ซึ่งจะมีลักษณะดังนี้

ERROR: HWAddressSanitizer: tag-mismatch on address 0x0042a0826510 at pc 0x007b24d90a0c
WRITE of size 1 at 0x0042a0826510 tags: 32/3d (ptr/mem) in thread T0
    #0 0x7b24d90a08  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x2a08)
    #1 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)
    #2 0x7b8f1db364  (/apex/com.android.art/lib64/libart.so+0x18f364)
    #3 0x7b8f2ad8d4  (/apex/com.android.art/lib64/libart.so+0x2618d4)

0x0042a0826510 is located 0 bytes to the right of 16-byte region [0x0042a0826500,0x0042a0826510)
allocated here:
    #0 0x7b92a322bc  (/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so+0x212bc)
    #1 0x7b24d909e0  (/data/app/com.example.hellohwasan-eRpO2UhYylZaW0P_E0z7vA==/lib/arm64/libnative-lib.so+0x29e0)
    #2 0x7b8f1e4ccc  (/apex/com.android.art/lib64/libart.so+0x198ccc)

ข้อความอาจตามด้วยข้อมูลการแก้ไขข้อบกพร่องเพิ่มเติม ซึ่งรวมถึง รายการเธรดที่ทำงานอยู่ในแอปพลิเคชัน แท็กของการจัดสรรหน่วยความจำที่อยู่ใกล้เคียง และ ค่ารีจิสเตอร์ CPU

ดูข้อมูลเพิ่มเติมเกี่ยวกับข้อความแสดงข้อผิดพลาดของ HWASan ได้ที่ทำความเข้าใจรายงาน HWASan

การสร้างไฟล์ปฏิบัติการบรรทัดคำสั่ง

คุณสามารถสร้างและเรียกใช้ไฟล์ที่ปฏิบัติการได้ซึ่งติดตั้งเครื่องมือด้วย HWASan ใน Android 14 และ ใหม่กว่า คุณสามารถใช้การกำหนดค่าเดียวกันตามที่อธิบายไว้ในสร้างสำหรับ ndk-build หรือ CMake สำหรับไฟล์ที่เรียกใช้งานได้ พุชไฟล์ที่เรียกใช้งานไปยังอุปกรณ์ที่ใช้ Android 14 ขึ้นไป แล้วเรียกใช้ตามปกติโดยใช้เชลล์

หากคุณใช้ libc++ โปรดตรวจสอบว่าคุณใช้ STL ที่แชร์และพุชไปยัง อุปกรณ์ แล้วตั้งค่า LD_LIBRARY_PATH เป็นไดเรกทอรีที่มี STL นั้นเมื่อ เรียกใช้ไบนารี

หากไม่ได้ใช้ Gradle โปรดดูเอกสารประกอบ NDK เพื่อดูวิธีสร้างจากบรรทัดคำสั่งด้วย CMake และ ndk-build

Android 13 หรือเวอร์ชันก่อนหน้า: การตั้งค่า

หากอุปกรณ์ใช้ Android 14 ขึ้นไป ให้ข้ามขั้นตอนนี้และทำตามวิธีการใช้ wrap.sh ในส่วนสร้าง นอกจากนี้ คุณยังเลือกทำตามส่วนนี้และข้ามวิธีการใช้ wrap.sh ได้ด้วย

ก่อน Android 14 แอปพลิเคชัน HWASan ต้องใช้บิลด์ HWASan ของ Android เพื่อเรียกใช้ คุณสามารถแฟลชอิมเมจ HWASan ที่สร้างไว้ล่วงหน้าไปยังอุปกรณ์ Pixel ที่รองรับ บิลด์พร้อมใช้งานที่ ci.android.com ซึ่งคุณสามารถคลิกสี่เหลี่ยมสำหรับบิลด์ที่ต้องการเพื่อรับลิงก์ Flash Build โดยคุณต้องทราบชื่อรหัสของโทรศัพท์

แฟลชบิลด์ของอุปกรณ์

คุณอาจไปที่ flash.android.com โดยตรงได้ง่ายกว่า เนื่องจากที่นั่น โฟลว์จะเริ่มต้นด้วยการตรวจหาอุปกรณ์ของคุณ และจะแสดงเฉพาะบิลด์ที่คุณใช้ได้ รูปภาพต่อไปนี้แสดงขั้นตอนการตั้งค่าในเครื่องมือนี้

เปิดใช้โหมดนักพัฒนาแอปในอุปกรณ์และเชื่อมต่อกับคอมพิวเตอร์โดยใช้ สาย USB คลิกเพิ่มอุปกรณ์ใหม่ เลือกอุปกรณ์จากกล่องโต้ตอบ แล้วคลิกเชื่อมต่อ

ตรวจหาอุปกรณ์ที่จะแฟลช เลือกอุปกรณ์ที่จะเชื่อมต่อ

หลังจากเชื่อมต่ออุปกรณ์แล้ว ให้คลิกอุปกรณ์เพื่อกำหนดค่าบิลด์ ในช่องเลือกรหัสบิลด์ ให้เลือกaosp-master-with-phones-throttled สาขาเพื่อเลือกอิมเมจที่ถูกต้องสำหรับอุปกรณ์ที่คุณเชื่อมต่อโดยอัตโนมัติ

เลือกอุปกรณ์ที่จะกะพริบ ยืนยันตัวเลือกการแฟลชและแฟลชอุปกรณ์

คลิกติดตั้งเพื่อแฟลชอุปกรณ์

ดูรายละเอียดเพิ่มเติมเกี่ยวกับการตั้งค่าที่จำเป็นได้ในเอกสารประกอบของ Android Flash Tool หรือจะดูวิธีการสร้างอิมเมจ HWASan จากแหล่งที่มาได้ในเอกสารประกอบของ AOSP