ضدعفونی کننده آدرس HWA

اندروید NDK از HWAddress Sanitizer که با نام HWASan نیز شناخته می‌شود، پشتیبانی می‌کند و از NDK r21 و اندروید 10 (سطح API 29) شروع می‌شود. HWASan فقط در دستگاه‌های 64 بیتی Arm موجود است.

HWASan یک ابزار تشخیص خطای حافظه مشابه ASan است. در مقایسه با ASan کلاسیک، HWASan دارای موارد زیر است:

  • سربار پردازنده مشابه (~۲ برابر)
  • سربار مشابه در اندازه کد (۴۰ تا ۵۰ درصد)
  • سربار رم بسیار کمتر (۱۰٪ - ۳۵٪)

HWASan همان مجموعه اشکالات ASan را شناسایی می‌کند:

  • سرریز یا سرریز بافر پشته و هیپ
  • استفاده از هیپ پس از آزادسازی
  • استفاده از پشته در خارج از محدوده
  • دابل فری یا وایلد فری

علاوه بر این، HWASan موارد زیر را نیز تشخیص می‌دهد:

  • استفاده از پشته پس از بازگشت

نمونه برنامه

یک برنامه نمونه نحوه پیکربندی یک نسخه ساخت برای hwasan را نشان می‌دهد.

ساختن

برای ساخت کد بومی (JNI) برنامه خود با HWAddress Sanitizer ، موارد زیر را انجام دهید:

ساخت ndk

در فایل 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 (گردل گرووی)

در فایل 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 نسخه ۲۷ یا جدیدتر، می‌توانید از کد زیر در build.gradle خود نیز استفاده کنید و نیازی به تغییر CMakeLists.txt ندارید:

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

این روش هنگام استفاده از ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false کار نخواهد کرد.

CMake (گردل کاتلین)

در فایل 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 نسخه ۲۷ یا جدیدتر، می‌توانید از کد زیر در build.gradle خود نیز استفاده کنید و نیازی به تغییر CMakeLists.txt ندارید:

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

این روش هنگام استفاده از ANDROID_USE_LEGACY_TOOLCHAIN_FILE=false کار نخواهد کرد.

اندروید ۱۴ یا جدیدتر: wrap.sh را اضافه کنید

اگر اندروید ۱۴ یا جدیدتر را اجرا می‌کنید، می‌توانید از اسکریپت wrap.sh برای اجرای برنامه‌ی اشکال‌زدایی‌شده‌ی خود روی هر دستگاه اندرویدی استفاده کنید. اگر تصمیم دارید مراحل موجود در دستورالعمل‌های راه‌اندازی را دنبال کنید، می‌توانید از این مرحله صرف‌نظر کنید.

دستورالعمل‌های بسته‌بندی اسکریپت wrap.sh را دنبال کنید تا اسکریپت wrap.sh زیر را برای arm64-v8a اضافه کنید.

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

اجرا کنید

اگر از نسخه اندروید قدیمی‌تر از ۱۴ استفاده می‌کنید، یا اسکریپت 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 را روی اندروید ۱۴ و جدیدتر بسازید و اجرا کنید. می‌توانید از همان پیکربندی شرح داده شده در Build برای ndk-build یا CMake برای فایل‌های اجرایی خود استفاده کنید. فایل‌های اجرایی را به دستگاهی که اندروید ۱۴ یا جدیدتر دارد، منتقل کنید و با استفاده از shell آن را به صورت عادی اجرا کنید.

اگر از libc++ استفاده می‌کنید، مطمئن شوید که از STL مشترک استفاده می‌کنید و آن را به دستگاه ارسال کنید و هنگام اجرای باینری، LD_LIBRARY_PATH روی دایرکتوری حاوی آن تنظیم کنید.

اگر از Gradle استفاده نمی‌کنید، برای یادگیری نحوه ساخت از خط فرمان با CMake و ndk-build به مستندات NDK مراجعه کنید.

اندروید ۱۳ یا قبل از آن: تنظیمات

اگر دستگاه شما اندروید ۱۴ یا جدیدتر را اجرا می‌کند، می‌توانید از این مرحله صرف نظر کنید و دستورالعمل‌های استفاده از wrap.sh را در بخش Build دنبال کنید. همچنین می‌توانید این بخش را دنبال کنید و دستورالعمل‌های استفاده از wrap.sh را نادیده بگیرید.

قبل از اندروید ۱۴، برنامه‌های HWASan برای اجرا به یک نسخه HWASan از اندروید نیاز داشتند. می‌توانید ایمیج‌های از پیش ساخته شده HWASan را روی دستگاه‌های پیکسل پشتیبانی شده فلش کنید. این نسخه‌ها در ci.android.com موجود هستند، جایی که می‌توانید روی مربع مربوط به نسخه مورد نظر خود کلیک کنید تا لینک Flash Build را دریافت کنید. این کار مستلزم آن است که نام کد گوشی خود را بدانید.

فلش کردن یک دستگاه

شاید راحت‌تر باشد که مستقیماً به flash.android.com بروید، زیرا در آنجا روند کار با شناسایی دستگاه شما شروع می‌شود و فقط نسخه‌هایی را که می‌توانید استفاده کنید به شما نشان می‌دهد. تصاویر زیر روند راه‌اندازی در این ابزار را نشان می‌دهند.

حالت توسعه‌دهنده را در دستگاه خود فعال کنید و آن را با استفاده از کابل USB به رایانه متصل کنید. روی افزودن دستگاه جدید کلیک کنید، دستگاه خود را از کادر محاوره‌ای انتخاب کنید و روی اتصال کلیک کنید.

شناسایی دستگاه برای فلش کردندستگاهی را برای اتصال انتخاب کنید

پس از اتصال دستگاه، برای پیکربندی ساخت، روی آن کلیک کنید. در کادر «انتخاب شناسه ساخت» ، شاخه aosp-master-with-phones-throttled را انتخاب کنید تا به طور خودکار تصویر صحیح را برای دستگاهی که متصل کرده‌اید انتخاب کند.

دستگاه را برای فلش انتخاب کنیدگزینه‌های فلش را تأیید کنید و دستگاه را فلش کنید

برای فلش کردن دستگاه خود، روی نصب (Install) کلیک کنید.

جزئیات بیشتر در مورد تنظیمات لازم در مستندات Android Flash Tool وجود دارد. همچنین می‌توانید مستندات AOSP را برای دستورالعمل‌های ساخت یک تصویر HWASan از منبع بررسی کنید.