DexPatcher: تصحيح ملفات APK لنظام Android باستخدام Java

click fraud protection

يسمح DexPatcher للمطورين بتصحيح ملفات APK باستخدام Java. وهذا له العديد من المزايا، واستخدام DexPatcher أسهل بكثير من أسلوب Smali الكلاسيكي.

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

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

وبشكل أكثر جدية... فلنبدأ من البداية. إذا لم تكن على دراية بتعديل تطبيقات Android، فربما تتساءل عن معنى smali. عادةً ما يستخدم المطورون لغة برمجة Java لترميز تطبيقات Android. ثم يقوم برنامج (المترجم) "بترجمة" هذا الرمز إلى تنسيق آخر مناسب لجهازك، مما ينتج عنه ملفات .dex موجودة داخل حزمة التطبيق (أو APK).

عند هذه النقطة، لن تتمكن من الوصول إلى كود المصدر الأصلي بعد الآن (إلا إذا كنت المطور أو كان التطبيق مفتوح المصدر). ومع ذلك، فإن ما لديك هو APK، لأنه هو ما تم تثبيته على جهازك. ومن خلاله، يمكنك الحصول على ملفات dex (عادةًclasses.dex) ثم محاولة ترجمتها مرة أخرى إلى تنسيق يمكنك فهمه. وهنا يأتي دور smali، كترجمة أكثر قابلية للقراءة ولكنها صادقة. يمكنك الذهاب خطوة أخرى إلى الأمام وترجمتها مرة أخرى إلى Java، على الرغم من أن هذه العملية ليست دقيقة بما فيه الكفاية - فسوف تحصل على نتيجة مفهومة، ولكن من المحتمل أنك لن تتمكن من ترجمتها بالعكس مرة أخرى حيث سيتم فقدان بعض التفاصيل على طول الطريق. بمعنى آخر، فإن أي تعديلات قد تجريها ستكون هباءً لأنك لن تتمكن من إعادته إلى ملف APK مرة أخرى لتثبيته على جهازك... على الأقل ليس بدون بذل الكثير من الجهد.

smali/baksmali هو في الواقع مجمع/مفكك لتنسيق dex - وهذا ما يعنيه حرفيًا باللغة الأيسلندية. ومع ذلك، فإننا عادةً ما نشير إلى التنسيق الذي يفهمه smali عندما نقول "Smali" (فكر فيه كتعليمات تحديد كل التفاصيل الصغيرة، حتى لو لم تكن جميعها مطلوبة من قبلنا نحن البشر - فهي بالتالي أكثر تفصيلاً من جافا). لاحظ أيضًا أن الشرح أعلاه مبسط بعض الشيء، ولكن يجب أن يكون تشبيهًا وثيقًا مع سهولة الفهم.

ما الذي يتعين على المطور فعله لتعديل التطبيق (دون الوصول إلى المصدر)، إذن؟ العملية هي أكثر أو أقل على النحو التالي:

  1. احصل على APK (من الويب أو من الجهاز).
  2. استخدم شيئًا مثل apktool لفك APK إلى Smali. (apktool يستخدم smali/baksmali، ولكنه يجعل من السهل جدًا فك ملفات APK وإعادة بنائها، ويهتم أيضًا بفك تشفير الموارد مثل ملفات XML.)
  3. قم باستخراج Class.dex من ملف APK، ثم استخدمه dex2jar وأخيرًا برنامج فك تشفير Java للحصول على كود Java (غير مكتمل، وغالبًا ما يكون معطلاً، ولكنه مفهوم في الغالب). (هذا أمر اختياري، ولكنه يمكن أن يكون مفيدًا لأن فهم Smali أكثر صعوبة).
  4. تحديد ما يجب تعديله.
  5. قم بتعديله فعليًا عن طريق تحرير كود Smali مباشرة.
  6. بدلًا من ذلك، اكتب التعديل في Java، وقم بتجميعه، وفك ترجمته مرة أخرى إلى Smali، ثم انسخ كود Smali الناتج.
  7. بمجرد انتهاء كل شيء، استخدم apktool مرة أخرى لإعادة بناء APK.
  8. قم بالتوقيع على APK (للتحقق من هوية المؤلف؛ يجب توقيع جميع الحزم) وتثبيته أخيرًا.

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

DexPatcher بواسطة عضو كبير في XDA لانشون يهدف إلى إصلاح هذه المشكلات، من خلال جعل العملية أكثر بساطة والسماح للمطورين بتجنب التعامل مع Smali تمامًا. بدلاً من ذلك، يمكن للمطورين كتابة التصحيحات في Java وحدها وجعل DexPatcher يتعامل مع كل شيء آخر.

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

  • مفتوح المصدر.
  • متعدد المنصات: يجب أن يعمل على Linux وMac وWindows.
  • ملفات التصحيح: التعديلات التي تجريها موجودة في ملفات تصحيح Java التي يمكنك مشاركتها بشكل مستقل.
  • جافا: إنها ليست سمالي.

يمكنك أيضًا الحصول على ميزة التحقق من الأخطاء أثناء وقت الإنشاء، بحيث تظهر الأخطاء في وقت مبكر من دورة التطوير. توفر Java المترجمة التحقق المعتاد من وقت الترجمة (مع إمكانية الوصول إلى رموز APK الأصلية)، ويفرض DexPatcher توافق المصدر والتصحيح عند التصحيح، مما يوفر معلومات مفيدة ويعطي تحذيرات عندما يبدو أنك تفعل شيئًا ما قانوني ولكن مريب.

بالإضافة إلى ذلك، يأتي DexPatcher مع مجموعة من البرامج النصية المساعدة (متوفر فقط على نظام التشغيل Linux، على الرغم من إمكانية نقله إلى منصات أخرى أيضًا). تهتم هذه بإعدادات مساحة العمل، واستخراج فئات APK المستهدفة ومواردها، وإلغاء ترجمة الفئات إلى Java (الملف CFR جافا المنقح يتم استخدامه للأخير)، وأخيرًا إنشاء ملف APK المصحح وتوقيعه بمجرد الانتهاء.

دعونا نلقي نظرة على مثال (على نظام التشغيل Linux):

قم بتثبيت البرامج النصية DexPatcher

$# Make a directory where we can test stuff out and enter it. 

$ mkdir xda-test

$cd xda-test

$ git clone https://github.com/Lanchon/DexPatcher-scripts.git dexpatcher # Clone the DexPatcher helper scripts repo.

$cd dexpatcher

$ chmod +x dxp-* # Not necessary, but for clarity: we need to make sure the files we'll call later are executable.

تكوين البرامج النصية DexPatcher

يفتح dxp.config في محرر النصوص المفضل لديك وتأكد من تغيير المتغيرات الضرورية لتناسب نظامك. ما عليك سوى تغيير السطر التالي للإشارة إلى موقع تثبيت Android SDK بدلاً من ذلك:

dxp_android_sdk_dir=(~/android/sdk)

(سيختار DexPatcher تلقائيًا أعلى إصدار متاح للنظام الأساسي. بالإضافة إلى ذلك، يمكنك أيضًا تعديل خيارات التكوين الأخرى لجعلها تستخدم إصداراتك الخاصة من بعض الأدوات بدلاً من الإعدادات الافتراضية المجمعة.)

لسهولة الوصول يمكننا إضافة com.dexpatcher الدليل لدينا طريق، أو حتى الارتباط الرمزي المختلف دكسب-* البرامج النصية إلى موقع موجود بالفعل في جهازك طريق، مثل ~/bin:

export PATH=$PWD:$PATH

تعديل التطبيق

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

سنأخذ تطبيق "Get ID" من خلال basil2style، وهو تطبيق يوضح لك بعض التفاصيل حول جهازك. هدفنا هو تعديل زر "نسخ" الخاص بـ "معرف الجهاز" وجعله يشارك هذا المعرف بدلاً من ذلك:

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

يمكننا أيضًا القيام بكل ذلك عبر الصدفة، باستخدام البرامج النصية المساعدة:

$cd dexpatcher # Go to our working directory. 

$ curl -O https://f-droid.org/repo/makeinfo.com.getid_1.apk # Download the APK.

$ dxp-setup-for-apk makeinfo.com.getid_1.apk # Unpack and decompile the APK.

$cd makeinfo.com.getid_1 # Go to the newly created directory where everything is unpacked/decompiled to.

$ dxp-create-keystore # Create the APK signing key. Press 6 times (or fill out the info), then "yes".

ستلاحظ بعض الدلائل المختلفة هناك:

  • فك تشفير: ستجد الموارد وسمالي هنا كما تم فك شفرتها apktool.
  • src: دليل فارغ. هذا هو المكان الذي سنضع فيه ملفات التصحيح الخاصة بنا.
  • src-cfr: هذا هو المكان CFR تم فك ترجمة التطبيق (مع الأخطاء). من الجيد البحث فيه لتحديد ما تريد تغييره (قد تحتاج أيضًا إلى موارد ومعرفاتها من دليل فك التشفير أعلاه، ولكن ليس لهذا المثال بالتحديد).
  • src-cfr-nodecode: كما هو مذكور أعلاه، ولكن يحتوي على بذرة فارغة فقط (لا يوجد كود، فقط هياكل عظمية). يمكنك استخدام هذه الملفات كأساس للتصحيح الخاص بك كما سنرى بعد قليل.

كما ذكرنا من قبل، نريد تغيير زر "نسخ" معرف الجهاز لمشاركة نص المعرف بدلاً من ذلك. إذا نظرنا حول الكود المصدري، فسنلاحظ أن زر نسخ معرف الجهاز (جهاز_نسخ) عند النقر يتم التعامل مع الحدث من خلال فئة مجهولة في src-cfr/makeinfo/com/getid/MainActivity.java. على الرغم من أنه يمكننا تعديلها هنا، فمن الأفضل عادة العثور على طريقة بديلة للقيام بذلك لأن الفئات المجهولة لها أسماء رقمية (اسم الفئة الرئيسية$SomeNumber، على سبيل المثال. النشاط الرئيسي$3) والتي قد تتغير بشكل غير متوقع بين الإصدارات.

بدلاً من ذلك، سنقوم بتسجيل فصلنا الخاص للحدث عن طريق تعديل ملف النشاط الرئيسي فصل. أولاً، لننسخ نسخة "الهيكل العظمي" من src-cfr-nocode/makeinfo/com/getid/MainActivity.java ل src/makeinfo/com/getid/MainActivity.java (تذكر ذلك src هو المكان الذي ستعيش فيه رقعة لدينا). (يمكنك أيضًا نسخ الإصدار بالكود الكامل إذا كنت تفضل ذلك، فهذه مسألة ذوق بحتة.)

يمكننا الآن تعديله على النحو التالي:

  • أضف الاستيراد اللازم للتعليق التوضيحي DexPatcher:
importlanchon.dexpatcher.annotation.*;
  • أضف علامة للإشارة إلى أننا نقوم بتحرير الفصل. قمنا أيضًا بتعيين الإجراء الافتراضي لأعضاء فئة التصحيح على يتجاهل، مما يعني أن الأعضاء موجودون ليتم الرجوع إليهم بواسطة التعليمات البرمجية الخاصة بنا أثناء تجميع Java، ولكن سيتم تجاهلهم بواسطة DexPatcher.
@DexEdit(defaultAction=DexAction.IGNORE)

publicclassMainActivity

// The reference to ActionBarActivity will be satisfied by symbols

// extracted from the app when we build the patch.

extendsActionBarActivity{

  • بالإضافة إلى ذلك، أضف أجسامًا فارغة إلى المنشئ و onCreate بالإضافة إلى جميع الطرق الأخرى التي نخطط لاستخدامها (تذكر أنه سيتم تجاهلها عندما يتم تطبيق التصحيح الخاص بنا فعليًا - نحن نضيفها فقط حتى نتمكن من الرجوع إليها هنا إذا أردنا ذلك). يمكنك أيضًا إضافة فقط محلي الكلمة الرئيسية بدلا من ذلك.
  • يمكننا بالفعل بناء التصحيح في هذه المرحلة، إذا كنت مهتمًا:
    $ dxp-make # Output: `patched.apk`.
    بسيطة جدا، أليس كذلك؟ دعونا نستمر، رغم ذلك - ما زلنا لم ننته بعد.
  • دعونا تحرير onCreate الآن لتحديد الخاصة OnClickListener حتى نتمكن من مشاركة معرف الجهاز بدلاً من نسخه إلى الحافظة:
    // Rename the target method so that we can still call it (the original)// if needed.@DexEdit(target="onCreate")protectedvoidsource_onCreate(Bundlevar1){}// Add our new custom method.@Override@DexAddprotectedvoidonCreate(Bundlevar1){// Call the original method:source_onCreate(var1);// Replace the text and handler:device_copy.setText("Share");device_copy.setOnClickListener(newDeviceCopyOnClick());}// Note that we don't use an anonymous class to avoid nameclashing with// MainActivity$1, which already exists.// We also could've defined a nested MainActivity.Patch class and used// an anonymous class in MainActivity.Patch.onCreate(), and then called// MainActivity.Patch.onCreate() from MainActivity.onCreate().@DexAddclassDeviceCopyOnClickimplementsView.OnClickListener{@OverridepublicvoidonClick(Viewobject){if(MainActivity.this.val){Intentintent=newIntent(Intent.ACTION_SEND);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_SUBJECT,"Device ID");intent.putExtra(Intent.EXTRA_TEXT,device.getText().toString());startActivity(Intent.createChooser(intent,"Share Device ID"));}else{Toast.makeText(MainActivity.this.getApplicationContext(),"Nothing to Share",0).show();}}}
  • يبدو أننا انتهينا الآن! يجب أن يبدو التصحيح الكامل هذا. يمكننا الآن إنشاء ملف APK المصحح وتثبيته:
    $ dxp-make$ adb install patched.apk
  • دعونا نلقي نظرة على النتيجة:

(شكرًا لـ Lanchon للمساعدة في نموذج التعليمات البرمجية!)

يتمتع Xpose بشعبية كبيرة، وذلك لسبب وجيه - فهو يجعل إنشاء التعديلات ومشاركتها وتثبيتها أسهل بكثير للمطورين والمستخدمين على حدٍ سواء. هناك بعض الاختلافات بين DexPatcher وXpose والتي قد تجعل البعض يفضل أحدهما على الآخر:

  1. يقوم Xpose بسحره من خلال ربط الأساليب في وقت التشغيل والسماح للمطورين بفعل شيء ما قبل أي طريقة أو بعدها أو بدلاً من ذلك. من ناحية أخرى، يقوم DexPatcher بتعديل كل شيء قبل وقت التشغيل وينتج ملف APK معدلًا ومستقلًا -- لا يزال من الممكن تشغيل التعليمات البرمجية قبل الطرق أو بعدها أو بدلاً منها، ولديك بالفعل بعض الإضافات حرية.
  2. إن إنتاج ملف APK مستقل يعني أنه لا يعتمد على أي إطار عمل خارجي. وهذا يعني أيضًا أن الجذر غير مطلوب لتعديل تطبيقات المستخدم.
  3. نظرًا لأنك أنشأت ملف APK جديدًا باستخدام DexPatcher، فسيتم توقيعه بشكل مختلف. وهذا يعني أنه لا يمكن للمستخدمين تلقي التحديثات الرسمية من المؤلف الأصلي، وقد يتسبب في بعض المشكلات مع تطبيقات مثل Google Apps إذا تم التحقق من التوقيعات.
  4. يمكن توزيع وتعديل الكود المصدري لكل من الوحدات وتصحيحات DexPatcher بسهولة. كما أنها تشترك في العديد من أوجه التشابه إذا كنت على دراية بكل منها.

لقد تحدثنا بما فيه الكفاية عن DexPatcher. لقد حان دورك لتجربته الآن، لذا توجه إلى موضوع منتدى DexPatcher للبدء على الفور!