اسکریپت پوشش پوسته

هنگام اشکال زدایی و نمایه سازی برنامه ها با کد بومی، اغلب استفاده از ابزارهای اشکال زدایی که باید در هنگام راه اندازی فرآیند فعال شوند مفید است. این مستلزم آن است که برنامه خود را به جای شبیه سازی از زیگوت در یک فرآیند تازه اجرا کنید. مثالها عبارتند از:

از اسکریپت wrap shell استفاده کنید

استفاده از wrap.sh آسان است:

  1. یک APK قابل اشکال زدایی سفارشی کامپایل کنید که موارد زیر را بسته بندی می کند:
    • یک اسکریپت پوسته به نام wrap.sh برای جزئیات بیشتر به ایجاد اسکریپت wrap shell و Package wrap.sh مراجعه کنید.
    • هر ابزار اضافی مورد نیاز اسکریپت پوسته شما (مانند باینری strace خود).
  2. APK قابل اشکال زدایی را روی دستگاه نصب کنید.
  3. برنامه را راه اندازی کنید.

اسکریپت wrap shell را ایجاد کنید

هنگامی که یک APK قابل اشکال زدایی را راه اندازی می کنید که حاوی wrap.sh است، سیستم اسکریپت را اجرا می کند و دستور شروع برنامه را به عنوان آرگومان ارسال می کند. اسکریپت مسئول راه اندازی برنامه است، اما می تواند هر محیط یا آرگومان را تغییر دهد. اسکریپت باید از دستور MirBSD Korn shell (mksh) پیروی کند.

قطعه زیر نحوه نوشتن یک فایل wrap.sh ساده را نشان می دهد که به تازگی برنامه را راه اندازی می کند:

#!/system/bin/sh
exec "$@"

اشکال زدایی Malloc

برای استفاده از malloc debug از طریق wrap.sh ، باید خط زیر را وارد کنید:

#!/system/bin/sh
LIBC_DEBUG_MALLOC_OPTIONS=backtrace logwrapper "$@"

ASan

نمونه ای از نحوه انجام این کار برای ASan در مستندات ASan وجود دارد.

بسته بندی wrap.sh

برای استفاده از wrap.sh ، APK شما باید قابل اشکال‌زدایی باشد. مطمئن شوید که تنظیم android:debuggable="true" در عنصر <application> در مانیفست اندروید شما پیکربندی شده باشد، یا اگر از Android Studio استفاده می کنید، یک ساختار اشکال زدایی را در فایل build.gradle پیکربندی کرده اید.

همچنین لازم است useLegacyPackaging در فایل build.gradle برنامه خود روی true تنظیم کنید. در بیشتر موارد، این گزینه به طور پیش فرض روی false تنظیم شده است، بنابراین ممکن است بخواهید برای جلوگیری از هرگونه غافلگیری، این گزینه را به صراحت روی true تنظیم کنید.

شما باید اسکریپت wrap.sh با کتابخانه های بومی برنامه بسته بندی کنید. اگر برنامه شما حاوی کتابخانه های بومی نیست، دایرکتوری lib را به صورت دستی به فهرست پروژه خود اضافه کنید. برای هر معماری که برنامه شما از آن پشتیبانی می‌کند، باید یک کپی از اسکریپت wrap shell در آن فهرست کتابخانه اصلی ارائه دهید.

مثال زیر طرح بندی فایل را برای پشتیبانی از معماری های ARMv8 و x86-64 نشان می دهد:

# App Directory
|- AndroidManifest.xml
|- …
|- lib
   |- arm64-v8a
      |- ...
      |- wrap.sh
   |- x86_64
      |- ...
      |- wrap.sh

Android Studio فقط فایل های .so را از دایرکتوری های lib/ بسته بندی می کند، بنابراین اگر کاربر اندروید استودیو هستید، باید فایل های wrap.sh خود را در دایرکتوری های src/main/resources/lib/* قرار دهید تا آنها به درستی بسته بندی می شوند.

توجه داشته باشید که resources/lib/x86 در رابط کاربری به صورت lib.x86 نمایش داده می شود، اما در واقع باید یک زیر شاخه باشد:

نمونه ای از بسته بندی wrap.sh در اندروید استودیو

هنگام استفاده از wrap.sh اشکال زدایی کنید

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

#!/system/bin/sh

cmd=$1
shift

os_version=$(getprop ro.build.version.sdk)

if [ "$os_version" -eq "27" ]; then
  cmd="$cmd -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable $@"
elif [ "$os_version" -eq "28" ]; then
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
  cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y $@"
fi

exec $cmd