Skip to content
KitploitKITPLOIT
أدواتالمدونة
إرسال
أدواتالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
simplify — آلة افتراضية لأندرويد ومُزِيل التعتيم | Kitploit
أدوات/GitHubGitHub/calebfenton/simplify
أمان أندرويدالتحليل الديناميكي (عزل)الهندسة العكسيةتحليل البرمجيات الخبيثةتحليل الملفات الثنائية
GitHubcalebfenton/simplify

simplify

آلة افتراضية لأندرويد ومُزِيل التعتيم

عرض المستودع
4.7k4551منذ 5 سنواتتمت المراجعة من قبل Kitploit

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

تبسيط

Build Status Coverage Status Coverity Scan Build Status

أداة إلغاء تعقيد أندرويد عامة

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

قبل وبعد

الكود على اليسار هو فك ترجمة لتطبيق معتم، والكود على اليمين تم إلغاء تعقيده.

الكثير من استدعاءات الدوال، بدون معنى واضح واو، كثير من الحرفية، الكثير من المعنى

نظرة عامة

يتكون المشروع من ثلاثة أجزاء: smalivm، simplify، وتطبيق العرض التوضيحي.

  1. smalivm: يوفر بيئة رملية (sandbox) آلة افتراضية لتنفيذ دوال Dalvik. بعد تنفيذ دالة، يعيد رسمًا بيانيًا يحتوي على جميع قيم السجلات والفئات الممكنة لكل مسار تنفيذ. يعمل حتى لو كانت بعض القيم غير معروفة، مثل عمليات الإدخال/الإخراج للملفات والشبكة. على سبيل المثال، أي شرط if أو switch بقيمة غير معروفة يؤدي إلى اتخاذ كلا الفرعين.
  2. simplify: يحلل رسوم التنفيذ البيانية من smalivm ويطبق تحسينات مثل نشر الثوابت، إزالة الكود الميت، إزالة الانعكاس، وبعض تحسينات الثقب. هذه التحسينات بسيطة إلى حد ما، ولكن عند تطبيقها معًا بشكل متكرر، فإنها تفك تشفير السلاسل النصية، وتزيل الانعكاس، وتبسط الكود بشكل كبير. لا يعيد تسمية الدوال والفئات.
  3. demoapp: يحتوي على أمثلة بسيطة ومعلقة بشدة لاستخدام smalivm في مشروعك الخاص. إذا كنت تبني شيئًا يحتاج إلى تنفيذ كود Dalvik، فاطلع عليه.

الاستخدام

root@kitploit:~
usage: java -jar simplify.jar <input> [options]
deobfuscates a dalvik executable
 -et,--exclude-types <pattern>   استبعاد الفئات والطرق التي تتضمن تعبيرًا منتظمًا (REGEX)، مثال: "com/android"، يتم تطبيقه بعد include-types
 -h,--help                       عرض هذه الرسالة
 -ie,--ignore-errors             تجاهل الأخطاء أثناء تنفيذ وتحسين الدوال. قد يؤدي هذا إلى سلوك غير متوقع.
    --include-support            محاولة تنفيذ وتحسين الفئات في حزم مكتبة دعم أندرويد، الافتراضي: false
 -it,--include-types <pattern>   قصر التنفيذ على الفئات والطرق التي تتضمن تعبيرًا منتظمًا (REGEX)، مثال: ";->targetMethod\("
    --max-address-visits <N>     التخلي عن تنفيذ دالة بعد زيارة نفس العنوان N مرة، يحد من الحلقات، الافتراضي: 10000
    --max-call-depth <N>         عدم استدعاء دوال بعد الوصول إلى عمق استدعاء N، يحد من التكرار وسلاسل الدوال الطويلة، الافتراضي: 50
    --max-execution-time <N>     التخلي عن تنفيذ دالة بعد N ثانية، الافتراضي: 300
    --max-method-visits <N>      التخلي عن تنفيذ دالة بعد تنفيذ N تعليمة في تلك الدالة، الافتراضي: 1000000
    --max-passes <N>             عدم تشغيل المحسنات على دالة أكثر من N مرة، الافتراضي: 100
 -o,--output <file>              إخراج الإدخال المبسط إلى FILE
    --output-api-level <LEVEL>   تعيين توافق DEX API للمخرجات إلى LEVEL، الافتراضي: 15
 -q,--quiet                      كن هادئًا
    --remove-weak                إزالة الكود حتى في حالة وجود آثار جانبية ضعيفة، الافتراضي: true
 -v,--verbose <LEVEL>            تعيين مستوى التفاصيل إلى LEVEL، الافتراضي: 0

البناء

يتطلب البناء تثبيت Java Development Kit 8 (JDK).

نظرًا لأن هذا المشروع يحتوي على وحدات فرعية لأطر عمل أندرويد، قم إما بالاستنساخ باستخدام --recursive:

root@kitploit:~
git clone --recursive https://github.com/CalebFenton/simplify.git

أو قم بتحديث الوحدات الفرعية في أي وقت باستخدام:

root@kitploit:~
git submodule update --init --recursive

ثم، لبناء jar واحد يحتوي على جميع التبعيات:

root@kitploit:~
./gradlew fatjar

سيكون ملف Simplify jar في simplify/build/libs/. يمكنك اختبار عمله عن طريق تبسيط تطبيق المثال المعتم المقدم. إليك كيفية تشغيله (قد تحتاج إلى تغيير simplify.jar):

root@kitploit:~
java -jar simplify/build/libs/simplify.jar -it "org/cf/obfuscated" -et "MainActivity" simplify/obfuscated-app.apk

لفهم ما يتم إلغاء تعقيده، اطلع على README تطبيق Obfuscated App.

استكشاف الأخطاء وإصلاحها

إذا فشل Simplify، جرب هذه التوصيات بالترتيب:

  1. استهدف فقط عددًا قليلاً من الدوال أو الفئات باستخدام الخيار -it.
  2. إذا كان الفشل بسبب تجاوز الحد الأقصى للزيارات، جرب استخدام قيم أعلى لـ --max-address-visits و --max-call-depth و --max-method-visits.
  3. جرب باستخدام -v أو -v 2 وأبلغ عن المشكلة مع السجلات وقيمة هاش (hash) لـ DEX أو APK.
  4. جرب مرة أخرى، ولكن لا تقطع التواصل البصري. يمكن لـ Simplify استشعار الخوف.

إذا كنت تبني على Windows وفشل البناء بخطأ مشابه لـ:

Could not find tools.jar. Please check that C:\Program Files\Java\jre1.8.0_151 contains a valid JDK installation.

هذا يعني أن Gradle غير قادر على العثور على مسار JDK صحيح. تأكد من تثبيت JDK، واضبط متغير البيئة JAVA_HOME على مسار JDK الخاص بك، وتأكد من إغلاق وإعادة فتح موجه الأوامر الذي تستخدمه للبناء.

المساهمة

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

الإبلاغ عن المشكلات

يرجى تضمين رابط لـ APK أو DEX والأمر الكامل الذي تستخدمه. هذا يسهل كثيرًا إعادة إنتاج (وبالتالي إصلاح) مشكلتك.

إذا لم تتمكن من مشاركة العينة، فالرجاء تضمين هاش الملف (SHA1، SHA256، إلخ).

استراتيجيات التحسين

نشر الثوابت

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

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
# Decrypts to: "Tell me of your homeworld, Usul."
move-result v0

في هذا المثال، يتم فك تشفير سلسلة مشفرة ووضعها في v0. نظرًا لأن السلاسل النصية "قابلة للتحويل إلى ثوابت"، يمكن استبدال move-result v0 بـ const-string:

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."

إزالة الكود الميت

الكود ميت إذا كانت إزالته لا يمكن أن تغير سلوك التطبيق. الحالة الأكثر وضوحًا هي إذا كان الكود غير قابل للوصول، مثل if (false) { // dead }). إذا كان الكود قابلًا للوصول، فقد يُعتبر ميتًا إذا لم يؤثر على أي حالة خارج الدالة، أي ليس له تأثير جانبي. على سبيل المثال، قد لا يؤثر الكود على القيمة المُعادة للدالة، أو يغير أي متغيرات فئة، أو ينفذ أي إدخال/إخراج. هذا أمر صعب التحديد في التحليل الثابت. لحسن الحظ، لا يحتاج smalivm إلى أن يكون ذكيًا. فهو فقط ينفذ كل شيء بغباء ويفترض وجود آثار جانبية إذا لم يكن متأكدًا. ضع في اعتبارك المثال من نشر الثوابت:

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
invoke-static {v0}, Lmy/string/Decryptor;->decrypt(Ljava/lang/String;)Ljava/lang/String;
const-string v0, "Tell me of your homeworld, Usul."

في هذا الكود، لم يعد invoke-static يؤثر على القيمة المُعادة للدالة ولنفترض أنه لا يفعل أي شيء غريب مثل كتابة بايتات إلى نظام الملفات أو مأخذ شبكة، لذلك ليس له آثار جانبية. يمكن إزالته ببساطة.

root@kitploit:~
const-string v0, "VGVsbCBtZSBvZiB5b3VyIGhvbWV3b3JsZCwgVXN1bC4="
const-string v0, "Tell me of your homeworld, Usul."

أخيرًا، يقوم أول const-string بتعيين قيمة لسجل، لكن هذه القيمة لا تُستخدم أبدًا، أي أن التعيين ميت. يمكن إزالته أيضًا.

root@kitploit:~
const-string v0, "Tell me of your homeworld, Usul."
"
مرحبًا!

### إزالة الانعكاس

أحد التحديات الرئيسية في التحليل الثابت لجافا هو الانعكاس (reflection). من المستحيل معرفة الوسائط لدوال الانعكاس دون إجراء تحليل دقيق لتدفق البيانات. هناك طرق ذكية وبارعة للقيام بذلك، لكن smalivm يفعلها بمجرد تنفيذ الكود. عندما يجد استدعاء دالة منعكسة مثل:

```smali
invoke-virtual {v0, v1, v2}, Ljava/lang/reflect/Method;->invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;

يمكنه معرفة قيم v0 و v1 و v2. إذا كان متأكدًا من القيم، يمكنه استبدال استدعاء Method.invoke() باستدعاء دالة فعلي غير منعكس. ينطبق الأمر نفسه على عمليات البحث عن الحقول والفئات المنعكسة.

تحسين الثقب (Peephole)

لكل ما لا يندرج بشكل نظيف في فئة معينة، هناك تحسينات الثقب. يتضمن ذلك إزالة عمليات check-cast غير المفيدة، واستبدال استدعاءات Ljava/lang/String;-><init> بـ const-string، وهكذا.

مثال على إلغاء التعقيد

قبل التحسين

root@kitploit:~
.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    move-result v0

    return v0
.end method

كل ما يفعله هذا هو v0 = 1.

بعد نشر الثوابت

root@kitploit:~
.method public static test1()I
    .locals 2

    new-instance v0, Ljava/lang/Integer;
    const/4 v1, 0x1
    invoke-direct {v0, v1}, Ljava/lang/Integer;-><init>(I)V

    invoke-virtual {v0}, Ljava/lang/Integer;->intValue()I
    const/4 v0, 0x1

    return v0
.end method

تم استبدال move-result v0 بـ const/4 v0, 0x1. هذا لأنه لا يوجد سوى قيمة إرجاع واحدة محتملة لـ intValue()I ونوع الإرجاع يمكن جعله ثابتًا. الوسائط v0 و v1 لا لبس فيها ولا تتغير. بمعنى آخر، هناك إجماع على القيم لكل مسار تنفيذ ممكن عند intValue()I. أنواع أخرى من القيم التي يمكن تحويلها إلى ثوابت:

  • الأرقام - const/4، const/16، إلخ.
  • السلاسل النصية - const-string
  • الفئات - const-class

بعد إزالة الكود الميت

root@kitploit:~
.method public static test1()I
    .locals 2

    const/4 v0, 0x1

    return v0
.end method

نظرًا لأن الكود أعلاه const/4 v0, 0x1 لا يؤثر على الحالة خارج الدالة (لا آثار جانبية)، يمكن إزالته دون تغيير السلوك. إذا كان هناك استدعاء دالة يكتب شيئًا إلى نظام الملفات أو الشبكة، فلا يمكن إزالته لأنه يؤثر على الحالة خارج الدالة. أو إذا كانت test()I تأخذ وسيطة قابلة للتغيير، مثل LinkedList، فلا يمكن اعتبار أي تعليمات تصل إليها ميتة.

أمثلة أخرى على الكود الميت:

  • التعيينات غير المشار إليها - تعيين سجلات وعدم استخدامها
  • التعليمات غير القابلة للوصول / التي لم يتم الوصول إليها - if (false) { dead_code(); }

الترخيص

هذه الأداة متاحة بموجب ترخيص مزدوج: ترخيص تجاري مناسب للمشاريع مغلقة المصدر وترخيص GPL يمكن استخدامه في البرامج مفتوحة المصدر.

اعتمادًا على احتياجاتك، يجب عليك اختيار أحدهما واتباع سياساته. تفاصيل السياسات والاتفاقيات لكل نوع ترخيص متاحة في ملفي LICENSE.COMMERCIAL و LICENSE.GPL.

قراءات إضافية

  • التنفيذ الافتراضي لـ Dalvik مع SmaliVM
  • Guillot, Yoann, and Alexandre Gazet. "Automatic Binary Deobfuscation." Journal in Computer Virology 6.3 (2010): 261-76
  • Unicorn - محاكي وحدة المعالجة المركزية (CPU) النهائي
  • Babak Yadegari, Saumya Debray. "Symbolic Execution of Obfuscated Code"
  • قصص نجاح:
    • تحميل الفئات الديناميكي في أندرويد مع تشفير "AES/CFB/NoPadding". ألق نظرة قبل & بعد. الأداة المستخدمة: #simplify. #Android #obfuscation #classencryption #dex
    • فك تشفير تشفير السلسلة النصية للبرامج الضارة
تنزيل الأداة