التفاف النص البرمجي بالصدفة

عند تصحيح أخطاء التطبيقات وإنشاء ملامحها باستخدام التعليمات البرمجية الأصلية، غالبًا ما يكون من المفيد استخدام أدوات تصحيح الأخطاء التي تحتاج إلى تمكين عند بدء التشغيل. يتطلب هذا تشغيل تطبيقك بعملية جديدة بدلاً من استنساخه من زيغوت. وتشمل الأمثلة ما يلي:

استخدام نص التفاف النص

يتميز استخدام "wrap.sh" بالسهولة:

  1. تجميع حزمة APK مخصَّصة يمكن تصحيح الأخطاء بها وتتضمّن ما يلي:
    • نص برمجي لأحد الأوامر باسم wrap.sh. يمكنك الاطّلاع على إنشاء النص البرمجي لـ wrap Shell وPackage wrap.sh لمزيد من التفاصيل.
    • أي أدوات إضافية يحتاجها النص البرمجي في واجهة الأوامر (مثل برنامج strace الثنائي).
  2. ثبِّت حزمة APK التي يمكن تصحيح الأخطاء بها على الجهاز.
  3. افتح التطبيق.

إنشاء نص التفاف النص البرمجي

عند تشغيل حزمة APK يمكن تصحيح الأخطاء بها وتحتوي على wrap.sh، ينفّذ النظام النص البرمجي ويمرِّر الأمر لبدء التطبيق كوسيطات. والنص البرمجي يكون مسؤولاً عن بدء تشغيل التطبيق، ولكنه قد يُجري أي تغييرات في البيئة أو الوسيطة. يجب أن يتّبع النص البرمجي بنية MirBSD Korn Shell (mksh).

يوضح المقتطف التالي طريقة كتابة ملف wrap.sh بسيط يؤدي إلى بدء تشغيل التطبيق:

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

تصحيح أخطاء تخصيص العملاء

لاستخدام تصحيح الأخطاء الخاطئ عبر wrap.sh، عليك تضمين السطر التالي:

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

أسان

وهناك مثال على كيفية إجراء ذلك لـ ASan في مستندات ASan.

الحزمة wrap.sh

للاستفادة من wrap.sh، يجب أن يكون ملف APK قابلاً للتصحيح. تأكَّد من أنّ android:debuggable="true"الإعداد قد تم ضبطه في العنصر <application> في بيان Android، أو إذا كنت تستخدم "استوديو Android" قد ضبطت إصدار تصحيح الأخطاء في ملف build.gradle.

من الضروري أيضًا ضبط useLegacyPackaging على true في ملف build.gradle لتطبيقك. في معظم الحالات، يتم ضبط هذا الخيار على false تلقائيًا، لذلك ننصحك بضبطه صراحةً على true لتجنُّب أي مفاجآت.

عليك تجميع النص البرمجي wrap.sh مع المكتبات الأصلية للتطبيق. وإذا لم يكن تطبيقك يحتوي على مكتبات أصلية، أضِف دليل lib يدويًا إلى دليل مشروعك. يجب توفير نسخة من نص التفاف النص البرمجي ضمن دليل المكتبة الأصلي لكل بنية متوافقة مع تطبيقك.

يوضّح المثال التالي تنسيق الملف الذي سيتوافق مع بنية ARMv8 وx86-64:

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

يضم "استوديو Android" ملفات .so فقط من أدلة lib/، لذا إذا كنت من مستخدمي "استوديو Android"، عليك وضع ملفات wrap.sh في أدلة src/main/resources/lib/* بدلاً من ذلك كي يتم تجميعها بشكل صحيح.

تجدر الإشارة إلى أنّه سيتم عرض resources/lib/x86 في واجهة المستخدم على شكل lib.x86، ولكن يُفترض أن يكون في الواقع دليلاً فرعيًا:

مثال على حزمة wrap.sh في &quot;استوديو Android&quot;

تصحيح الأخطاء عند استخدام 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