
مفكك أصلي لـ APK و DEX مكتوب بلغة Rust
محلل DEX الأولي بلغة Rust في src/native_dex.rs يتبنى منطق التحليل من
JADX v1.5.6، مثبّت على الالتزام
28ff15e4ae69950aebea110a13e5ab895d234dfc.
JADX حقوق النشر مملوكة لـ Skylot والمساهمين فيه؛ إشعارات مشروع Android مفتوح المصدر
والإشعارات الأخرى من المنبع محفوظة في NOTICE.
التنفيذ المرجعي هو
إضافة إدخال DEX،
بما في ذلك DexReader وsections/DexHeader وsections/SectionReader
وsections/DexClassData وutils/Leb128.
تعديلات RDX تترجم منطق المحلل إلى Rust مع وصول بايت مُتحقق منه، ونشر أخطاء صريح، وتمثيلات فئات/أعضاء مملوكة لـ RDX. مُصدِّر المصدر الأصلي هو كود RDX جديد. هذا محلل أولي وجزئي وتنفيذ محرك أصلي، وليس منفذًا كاملًا لخط أنابيب فك التجميع في JADX أو ادعاء بتغطية مخرجات مكافئة.
الملفات أدناه هي نسخ غير معدّلة تم تنزيلها من الإصدار المثبّت:
8dada3edaf50dbc082c9a125058f25def75e625a).5c0b69a0f5298e0b329e33e860f7626f0c2c3891).يُحتفظ بإشعار المنبع الكامل، بما في ذلك إشعارات المكتبات والأيقونات المُضمَّنة تاريخيًا. لا يعني الاحتفاظ أن محلل Rust يدمج كل تلك المكتبات أو الأصول. لم يعد تنفيذ Java وتبعياته وقت التشغيل يُشحن.
يجب أن تتضمن التوزيعات التي تحتوي على المحلل المُكيَّف الترخيص والإشعارات المعمول بها. يجب أن تحتفظ التغييرات المستمدة من ملفات منبع إضافية بإشعاراتها وتوسّع تعيين المصدر هذا مع نمو المنفذ.
src/native_resources.rs يعيّن إرسال القطع، والمساحة الاسمية، والعنصر، وتحليل
السمات المكتوبة من JADX v1.5.6 المثبّت
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
إلى Rust أصلي. قارئ مجمّع النصوص ومُصدِّر XML المحدود هما كود RDX.
يتحقق المفكك من حدود الإدخال/القطع/النص، ويدعم مجمّعات UTF-8/UTF-16،
ويتعامل مع قيم السمات المكتوبة الشائعة في Android دون وقت تشغيل Java.
تبقى معرّفات الموارد رقمية: لم يتم بعد نقل البحث عن رموز ARSC وأسماء
تعدادات/أعلام البيان. هذا ليس النظام الفرعي الكامل للموارد من المنبع.
src/native_java/ هي طبقة RDX المحافظة لخفض قيم السجلات بلغة Rust وإصدار Java
فوق قارئ DEX المُكيَّف. تتعامل مع التعليمات المكتوبة المدعومة، والفروع الأمامية، والحلقات البسيطة و
المفاتيح الأمامية مع تجسيد صريح للتأثيرات وتعيينات مصدر مُولَّدة.
معالجة أكواد العمليات للمصفوفات/الأنواع تتبع مواصفات تعليمات AOSP DEX.
إنها ليست منفذًا لخط أنابيب CFG/SSA/استنتاج الأنواع في JADX ولا تدّعي
تغطية إعادة بنائه. تحتفظ الطرق غير المدعومة بمخرجات DEX الأصلية.
src/native_cfg.rs يتبنى نهج التقسيم/الربط من JADX المثبّت
BlockSplitter.java.
يعمل تنفيذ Rust مباشرة على وحدات كود DEX المُتحقق منها، ويحتفظ
بتعليمات goto والإزاحات الأصلية، ويستبعد بيانات الحمولة، ويعزل بشكل محافظ
التعليمات المحمية للحواف الاستثنائية. لا ينفذ بعد
تحويلات الكتل الاصطناعية في JADX، أو SSA، أو بناء المناطق. تحليل
المسيطر هو مرحلة منفصلة موصوفة أدناه.
تُعرَض هذه المرحلة من خلال تدقيق مجموعة منفصل؛ لا يزال مُصدِّر المصدر في واجهة المستخدم الرسومية
يستخدم خفض قيم السجلات الحالي. راجع
docs/jadx-port-plan.md للمرات المتبقية.
src/native_dominators.rs يتبنى
DominatorTree.java المثبّت:
خوارزمية Cooper/Harvey/Kennedy التكرارية للمسيطر المباشر، وتقاطع
السلف، ومسارات حدود السيطرة. تحافظ تعديلات Rust على معرّفات الكتل الأصلية،
وتستخدم اجتيازًا تكرارياً بترتيب عكسي لاحق، وتحدّ من تخزين العمل/الحدود،
وتستخدم فترات الشجرة لاستعلامات السيطرة بدلاً من مجموعات بتات المسيطر لكل كتلة.
يتعامل سلف إدخال افتراضي مع الحواف الخلفية إلى مدخل الطريقة.
الوصولية من مدخل الطريقة الفعلي عبر الحواف العادية والاستثنائية المحافظة؛
تُبلَّغ كتل المعالجات المنفصلة كغير قابلة للوصول.
هذا تحليل المسيطر، وليس مرور التحويل الكامل BlockProcessor.
src/native_ir.rs يتبنى تعيين معاملات عائلة التعليمات من
InsnDecoder.java المثبّت.
قارئ معاملات DEX الخام المُتحقق منه يتبع تنسيقات تعليمات AOSP وهو كود
RDX. يحتفظ بالإزاحات/أكواد العمليات، وقراءات وكتابات السجلات المرتبة، وعروض الكلمات،
والقيم الحرفية، والمراجع المفهرسة، والسلوك الرامي المحافظ. على عكس المنبع،
لا يحل بعد إدخالات المجمّع، ولا يدمج نتائج الاستدعاء، ولا ينفذ استنتاج الأنواع.
تبقى وسائط الاستدعاء كلمات سجلات خام مرتبة حتى حل التوقيع.
src/native_calls.rs الآن يحل إدخالات مجمّع الطرق ويجمّع كلمات
المستقبل/الوسائط حسب نماذجها الأولية الفعالة، متبعًا نفس اصطلاحات
الاستدعاء/النتيجة في InsnDecoder المثبّت. يتعامل مع الوسائط العريضة، وأصحاب المصفوفات،
والنماذج الأولية الثانوية متعددة الأشكال، والمصفوفات المملوءة، ويربط تعليمات
move-result المكتوبة المجاورة. ترفض الاستدعاءات المخصصة صراحةً بيانات موقع الاستدعاء المفقودة.
هذا ربط التوقيع، وليس حل الإرسال الافتراضي أو SSA.
تصف فئات السجلات قيود عرض التخزين/المرجع، وليس أنواع Java المستنتجة. يتشارك CFG وفك ترميز المعاملات مفكك عرض تعليمات واحد؛ يبقى مُصدِّر المصدر القديم منفصلاً بينما يُبنى خط أنابيب التحليل هذا.
src/native_dex_metadata.rs يفك ترميز القيم المُرمَّزة، وقوائم معالجات try/catch،
ومجموعات التعليقات التوضيحية المشتركة للفئات/الحقول/الطرق/المعاملات من
تنسيق AOSP DEX.
الإزاحات المُتحقق منها، وميزانيات التخصيص/العمل، وتخزين المعالجات المشترك، وتمثيلات
Rust هي كود RDX. src/native_java/annotations.rs يعرض قيم التعليقات التوضيحية
الشائعة في Java، محتفظًا بروابط الأنواع/التعدادات والنصوص/الأحرف المُهرَّبة. يتبع وضع التعليقات التوضيحية
AnnotationGen.java المثبّت.
تُعرض تعليقات البناء/وقت التشغيل التوضيحية، بما في ذلك على الطرق ذات أجسام
DEX الاحتياطية. تبقى تعليقات النظام التوضيحية بيانات وصفية؛ كما يُعرض Throws كجملة throws.
تُوسَم قيم Java غير المدعومة صراحةً. لا تُعاد بناء إعدادات التعليقات التوضيحية الافتراضية
والبيانات الوصفية للتصحيح بالكامل.
src/native_java/numeric.rs وstrings.rs وliveness.rs ومُصدِّر الاستثناءات
هي تنفيذات RDX فوق دلالات تعليمات DEX. حدودها الاحتياطية المحافظة
وتركيبات سلوك Rust المستقلة موثقة في docs/native-engine.md وdocs/validation.md. لا
تنفذ أو تدمج كود Java من المنبع.
src/native_ssa.rs يتبنى إدراج phi على حدود السيطرة مع تقليم live-in وإعادة
التسمية من JADX المثبّت
SSATransform.java.
تستخدم تعديلات Rust اجتيازًا تكرارياً، وهويات كلمات محدودة، وكتل نجاح عادية
اصطناعية للحفاظ على الحالة الاستثنائية قبل الكتابة. يستبدل الأخير
إصلاح حواف try بعد إعادة التسمية في المنبع. يبقى تبسيط Phi غير منقول؛
يُوصف استنتاج الأنواع الجزئي أدناه. native_call_values.rs يربط
قيود التوقيع الموجودة بكلمات SSA. لا يُنفَّذ أي كود Java من المنبع.
src/native_types.rs يتبنى فصل الإسناد/حدود الاستخدام وتسلسل
النشر من JADX المثبّت TypeInferenceVisitor.java
وTypeUpdate.java.
قائمة العمل المحدودة في Rust، وفحوصات أزواج الكلمات، والبدائل الحرفية، والنتائج
الصريحة غير المحلولة/المتعارضة هي تعديلات RDX. هذا استنتاج جزئي:
مستمعو عناصر المصفوفات ينشرون الآن أنواع التحميل وقيود التخزين. يبقى
الاستنتاج العكسي العام للمصفوفات، والحدود العليا الدنيا للمراجع، والأدوية العامة، وإدراج
التحويلات غير مكتمل.
src/native_constructors.rs يتبع سلاسل إسناد SSA كما في
ConstructorVisitor.java المثبّت.
يتحقق RDX من سيطرة التخصيص ويحتفظ بالأصل والمالك المستدعى الأصلي.
يُوسَم المالك المختلف لإعادة الاستهداف فقط عندما يثبت التسلسل الهرمي أنه
سلف لنوع التخصيص. يتبع التسلسل عبر سلف مُثبَت على
this ConstructorInsn.java المثبّت. لا يزيل هذا التحليل أو ينقل
التعليمات، ولا يثبت صلاحية حالة التهيئة، ولا يصدر المُنشئات.
مسار التخصيص المتداخل المحدود في native_java/allocation_lowering.rs الآن
يستهلك روابط مُنشئ SSA هذه. هويات التخصيص/الاستدعاء الدقيقة و
فحص حدث تأثير RDX يبوّبان تعبيرات Java للالتقاط المشترك. هذا التكامل
ليس منفذًا لخط أنابيب المناطق/توليد الكود الكامل في JADX؛ يبقى إصدار إعادة استهداف المالك،
ومناطق الاستثناءات، والتحقق العام من حالة التهيئة
غير مدعوم في هذا المسار.
علاقات إسناد المصفوفات في native_hierarchy.rs تتبع
JLS 4.10.3:
التغاير المرجعي للمكونات، والمكونات الأولية الثابتة، والأنواع الفائقة القياسية
Object/Cloneable/Serializable. تداخل الواصفات محدود؛ تبقى علاقات الفئات
الخارجية المفقودة غير معروفة.
يتضمن التسلسل الهرمي الصغير للمنصة أيضًا حواف واجهات مُتحقق منها لـ Throwable / Serializable وSQLException / Iterable. تتجنب هذه الحقائق إجابات الأنواع الفرعية السلبية الخاطئة من رسم الاستثناءات الأبوي السابق فقط؛ وهي لا تشكل مسار فئات كامل لمنصة Android.
يتعرف مفكك التخصيص المحدود على نتائج StringBuilder.append(String)
المتجاهلة، مسترشدًا بنمط استخدام builder غير المتسلسل في
SimplifyVisitor.convertInvoke المثبّت.
يحتفظ RDX باستدعاءات المُنشئ/append الفعلية وتتبعات التأثير الدقيقة؛ ولا
ينفذ تحويل تسلسل النصوص الكامل في المنبع. يُقبل فقط فئة المنصة النهائية الدقيقة
والتحميل الزائد مع عقد إرجاع المستقبل الموثق؛ تبقى الطرق
التي تبدو انسيابية التعسفية غير مدعومة. راجع
StringBuilder.append(String).
إصدار invoke-super للفئة في native_java/method.rs يتبع معالجة الفئة الفائقة
في InsnGen.callSuper/getClassForSuperCall المثبّت.
يثبت RDX نسب الفئة الفائقة الصارم باستخدام تسلسله الهرمي الثابت المحدود،
بدلاً من اشتراط أن يساوي مالك طريقة DEX الأب المباشر. يصدر
super.method(...) ويحتفظ بتوقيع DEX الأصلي في البيانات الوصفية للتنقل.
يجب أن يظل المستقبل هو المثيل الحالي. تبقى الإعدادات الافتراضية للواجهات، واستدعاءات super المؤهلة
للفئة المحيطة، والنسب غير المكتمل/الغامض غير مدعومة.
تُحدَّد تمييزات إرسال الفئة/الواجهة بواسطة
وثائق invoke-kind في AOSP.
ConstructorVisitor.processInvoke في JADX المثبّت يزيل
NEW_INSTANCE الأصلي ويستبدل استدعاء المُنشئ في مكانه؛ ثم يصدر InsnGen
new Class(arguments). مصادر المنبع ذات الصلة:
يحتفظ allocation.rs الأصلي في RDX بإعادة بناء تعبيره الأكثر صرامة أولاً.
للنوافذ المسطحة فقط، يمكنه تجهيز إعلانات الالتقاط المرتبة ووضع new
في موضع المُنشئ، مطابقًا نهج إعادة البناء القابل للقراءة في المنبع.
على عكس تصنيفات إعادة الترتيب الأوسع في المنبع، لا يزال RDX يفحص
جميع أحداث cast/call/read/string المسجلة بترتيبها الأصلي. يمكن لنقل
التخصيص المتعمد تغيير توقيت تهيئة الفئة، والربط، وفشل التخصيص؛
لا تثبت تغطية المخرجات التكافؤ الدلالي الكامل.
src/native_java/synchronized.rs يتبنى نهج إعادة بناء
الإدخال/الجسم/خروج المراقب في jadx-core/src/main/java/jadx/core/dex/visitors/regions/maker/SynchronizedRegionMaker.java المثبّت.
يضيف تنفيذ Rust اجتياز CFG محدود، وفحوصات تغطية كتابة السجلات
والاستثناءات المفككة، والتحقق الدقيق من التنظيف، والرفض المحافظ
لأشكال الاستثناءات المتداخلة/متعددة الإصدار/المختلطة. إنه تنفيذ جزئي،
وليس منفذًا كاملًا لصانع المناطق في المنبع. تبقى شروط SPDX/الترخيص الأصلية
والإشعارات مغطاة بالملفات أعلاه.
native_java/names.rs يتبع فصل الهوية الأصلية والأسماء المستعارة
الصالحة للمصدر في JADX المثبّت
RenameVisitor.java،
خاصةً checkClassName وcheckPackage. يستخدم RDX مخطط الاسم المستعار السداسي
UTF-8 التبايني الموجود بدلاً من مزود الأسماء المستعارة القابل للتكوين في JADX ومرور
التصادم العام. تستخدم الرؤوس والمُنشئات ومعاملات الأنواع والاستيرادات الأسماء المستعارة؛
تحتفظ روابط المصدر بأسماء DEX الأصلية. هذا ليس منفذًا كاملًا لـ RenameVisitor.
تتعامل المجموعة الفرعية للمنطقة المتزامنة أيضًا مع مزلاج حلقة غير رامٍ خارج الفاصل المحمي في DEX وتصدر حلقات بالكامل داخل منطقة مراقب مُثبَتة. تحتفظ بفصل منطقة المراقب في الصانع المثبّت مع اشتراط التغطية لكل تعليمة جسم رامية بخلاف الإصدار المُثبَت.
native_java/finally_regions.rs يستخدم نهج التعرف على التنظيف المكرر
في MarkFinallyVisitor.java المثبّت في JADX.
هذه مجموعة فرعية محدودة بلغة Rust، وليست منفذًا كاملًا للزائر: استدعاء تنظيف
void واحد بإدخال مستقر، ونسخة عادية واحدة، وإعادة رمي شاملة،
والتقاط مكتوب محيط بمسارات نهائية. يفحص إرسال الاستثناء الأصلي
لكل تعليمة، وحدود تدفق التحكم، ومعاملات التنظيف، وروابط المصدر قبل الإصدار.
لا تزال التخطيطات المتداخلة غير المدعومة ترجع للاحتياطي.
تستند البيانات الوصفية الدقيقة لاستثناءات إطار عمل Android إلى إعلانات المنصة: ActivityNotFoundException، وRemoteException، وIBinder.transact.
تتبع واجهة مستخدم مقتطف الطريقة وتنسيق التسجيل في src/frida_snippet.rs
JADX FridaAction.
يقرأ مُولِّد Rust واصفات رموز DEX الدقيقة، ويختار دائمًا
التحميل الزائد الدقيق، ويستخدم أسماء الوسائط الموضعية، ويستدعي ذلك التحميل الزائد الملتقط.
يُحدَّد نطاق كل مقتطف داخل Java.perform بحيث لا يمكن للمقتطفات الملصقة أن تستبدل
مقابض طرق بعضها البعض. لا تُنفَّذ مقتطفات على مستوى الفئة والحقل.