অ্যান্ড্রয়েড এনডিকে API লেভেল 27 (অ্যান্ড্রয়েড ও এমআর 1) থেকে শুরু করে অ্যাড্রেস স্যানিটাইজার (এছান নামেও পরিচিত) সমর্থন করে।
ASan স্থানীয় কোডে মেমরি বাগ সনাক্ত করার জন্য একটি দ্রুত কম্পাইলার-ভিত্তিক টুল। ASan সনাক্ত করে:
- স্ট্যাক এবং হিপ বাফার ওভারফ্লো/আন্ডারফ্লো
- বিনামূল্যে পরে গাদা ব্যবহার
- সুযোগের বাইরে স্ট্যাক ব্যবহার করুন
- ডাবল ফ্রি/ওয়াইল্ড ফ্রি
ASan-এর CPU ওভারহেড মোটামুটি 2x, কোড সাইজ ওভারহেড 50% এবং 2x এর মধ্যে, এবং মেমরি ওভারহেড বড় (আপনার বরাদ্দ প্যাটার্নের উপর নির্ভর করে, কিন্তু 2x এর ক্রম অনুসারে)।
নমুনা অ্যাপ
একটি নমুনা অ্যাপ দেখায় কিভাবে আসানের জন্য একটি বিল্ড ভেরিয়েন্ট কনফিগার করতে হয়।
নির্মাণ করুন
ঠিকানা স্যানিটাইজার দিয়ে আপনার অ্যাপের নেটিভ (JNI) কোড তৈরি করতে, নিম্নলিখিতগুলি করুন:
ndk-বিল্ড
আপনার Application.mk এ:
APP_STL := c++_shared # Or system, or none.
APP_CFLAGS := -fsanitize=address -fno-omit-frame-pointer
APP_LDFLAGS := -fsanitize=address
আপনার Android.mk-এর প্রতিটি মডিউলের জন্য:
LOCAL_ARM_MODE := arm
সিমেক
আপনার মডিউল এর build.gradle এ:
android {
defaultConfig {
externalNativeBuild {
cmake {
// Can also use system or none as ANDROID_STL.
arguments "-DANDROID_ARM_MODE=arm", "-DANDROID_STL=c++_shared"
}
}
}
}
আপনার CMakeLists.txt-এ প্রতিটি লক্ষ্যের জন্য:
target_compile_options(${TARGET} PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS -fsanitize=address)
চালান
Android O MR1 (API স্তর 27) দিয়ে শুরু করে একটি অ্যাপ্লিকেশন একটি মোড়ানো শেল স্ক্রিপ্ট সরবরাহ করতে পারে যা অ্যাপ্লিকেশন প্রক্রিয়াটিকে মোড়ানো বা প্রতিস্থাপন করতে পারে। এটি একটি ডিবাগযোগ্য অ্যাপ্লিকেশনকে তাদের অ্যাপ্লিকেশন স্টার্টআপ কাস্টমাইজ করার অনুমতি দেয়, যা উত্পাদন ডিভাইসে ASan ব্যবহার করতে সক্ষম করে।
- অ্যাপ্লিকেশন ম্যানিফেস্টে
android:debuggable
যোগ করুন। - আপনার অ্যাপের
build.gradle
ফাইলেuseLegacyPackaging
true
হিসাবে সেট করুন। আরও তথ্যের জন্য মোড়ানো শেল স্ক্রিপ্ট গাইড দেখুন। - আপনার অ্যাপ মডিউলের
jniLibs
এ ASan রানটাইম লাইব্রেরি যোগ করুন। আপনার
src/main/resources/lib
ডিরেক্টরিতে প্রতিটি ডিরেক্টরিতে নিম্নলিখিত বিষয়বস্তু সহwrap.sh
ফাইল যোগ করুন।#!/system/bin/sh HERE="$(cd "$(dirname "$0")" && pwd)" export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1 ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so) if [ -f "$HERE/libc++_shared.so" ]; then # Workaround for https://github.com/android-ndk/ndk/issues/988. export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so" else export LD_PRELOAD="$ASAN_LIB" fi "$@"
আপনার প্রজেক্টের অ্যাপ্লিকেশন মডিউলটির নাম app
বলে ধরে নিচ্ছি, আপনার চূড়ান্ত ডিরেক্টরি কাঠামোতে নিম্নলিখিতগুলি অন্তর্ভুক্ত করা উচিত:
<project root>
└── app
└── src
└── main
├── jniLibs
│ ├── arm64-v8a
│ │ └── libclang_rt.asan-aarch64-android.so
│ ├── armeabi-v7a
│ │ └── libclang_rt.asan-arm-android.so
│ ├── x86
│ │ └── libclang_rt.asan-i686-android.so
│ └── x86_64
│ └── libclang_rt.asan-x86_64-android.so
└── resources
└── lib
├── arm64-v8a
│ └── wrap.sh
├── armeabi-v7a
│ └── wrap.sh
├── x86
│ └── wrap.sh
└── x86_64
└── wrap.sh
স্ট্যাক ট্রেস
অ্যাড্রেস স্যানিটাইজারকে প্রতিটি malloc
/ realloc
/ free
কলে স্ট্যাক খুলে দিতে হবে। এখানে দুটি বিকল্প আছে:
একটি "দ্রুত" ফ্রেম পয়েন্টার-ভিত্তিক আনউইন্ডার। বিল্ডিং বিভাগে নির্দেশাবলী অনুসরণ করে এটি ব্যবহার করা হয়।
একটি "ধীর" CFI আনওয়াইন্ডার। এই মোডে ASan
_Unwind_Backtrace
ব্যবহার করে। এটির প্রয়োজন শুধুমাত্র-funwind-tables
, যা সাধারণত ডিফল্টরূপে সক্রিয় থাকে।
দ্রুত আনওয়াইন্ডার হল malloc/realloc/free-এর জন্য ডিফল্ট। মারাত্মক স্ট্যাক ট্রেসের জন্য স্লো আনওয়াইন্ডার ডিফল্ট। আপনার wrap.sh-এ ASAN_OPTIONS
ভেরিয়েবলে fast_unwind_on_malloc=0
যোগ করে সমস্ত স্ট্যাকের ট্রেসের জন্য ধীর গতির আনউইন্ডার সক্ষম করা যেতে পারে।