هل هناك أي java decompiler يمكنه إلغاء توحيد المكالمات بشكل صحيح إلى طرق محملة بشكل صحيح؟ [مغلق

StackOverflow https://stackoverflow.com/questions/2840183

  •  27-09-2019
  •  | 
  •  

سؤال

النظر في هذا (IMHO بسيط) مثال:

public class DecompilerTest {
    public static void main(String[] args) {
        Object s1 = "The", s2 = "answer";
        doPrint((Object) "You should know:");
        for (int i = 0; i < 2; i++) {
            doPrint(s1);
            doPrint(s2);
            s1 = "is";
            s2 = new Integer(42);
        }
        System.out.println();
    }

    private static void doPrint(String s1) {
        System.out.print("Wrong!");
    }

    private static void doPrint(Object s1) {
        System.out.print(s1 + " ");
    }
}

قم بتجميعه بمستوى المصدر/المستهدف 1.1 بدون معلومات تصحيح (أي يجب أن تكون هناك معلومات متغيرة محلية) ومحاولة فك تشفيرها. جربت Jad و JD-Gui و Fernflower ، وجميعهم حصلوا على واحد على الأقل من الخاطئين (أي البرنامج مطبوع "خطأ!" مرة واحدة على الأقل)

هل لا يوجد في الحقيقة أي جافا decompiler يمكن أن يستنتج القوالب الصحيحة حتى لا تسمي الحمل الزائد الخاطئ؟

تعديل: المستوى المستهدف 1.1 بحيث لا يوجد أي من معلومات التحقق السريع الخاصة بـ Java6 هذه. قد يمنح ذلك decompiler فكرة أن S1 قد تم الإعلان عنها باسم Object وليس كما String. يجب أن يكون Decompilers قادرًا على فك الرمز حتى بدون هذه المعلومات (وليس بالضرورة الحصول على النوع المتغير الأصلي ، ولكن يُظهر نفس السلوك) ، خاصة وأن الكثير من المحتالين يقومون بتجريده أيضًا.

ما أخطأه في حدوث خطأ:

  • لقد فاتهم الممثلين (Object) في المكالمة الأولى.
  • استنتجوا نوع s1 ان نكون String, ، لكن نسيت إضافة ممثلين إلى المكالمة doPrint (بحيث يتم استدعاء إصدار السلسلة بدلاً من إصدار الكائن).
  • واحد كربي واحد (لم أدرج حتى) حتى أن نوع من s2 لتكون سلسلة ، تسبب رمز لا يمكن توسيعه.

في أي حال ، لا يستدعي هذا الرمز أبدًا String الحمل الزائد ، ولكن رمز decompiled فعل.

هل كانت مفيدة؟

المحلول

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

الكشف: أنا مؤلف كتاب Krakatau.

نصائح أخرى

هالو ميهي ،

اسف على الجواب المتاخر. أقوم بنسخ إجابتي من http://www.reversed-java.com/fernflower/forum؟threadfolder=2_de

مشكلتك هي في الواقع واحدة معروفة. دعونا نرى:

1) لا يحتوي رمز bytecode النقي على أي معلومات حول نوع متغيرات الكائن ، لذلك في الممر الأول S1 و S2 يتم الإعلان عنهما ككائن.

2) يحاول Decompiler جاهزًا تعيين أفضل نوع ممكن لكل متغير (= "مبدأ" أضيق "يتم تنفيذه في Fernflower). لذلك يتم تحديد S1 و S2 بشكل صحيح كحالات من السلسلة.

3) استدعاء doprint أعطينا رابطًا مباشرًا للطريقة الصحيحة
doprint static static void (كائن S1)

4) كل شيء على ما يرام حتى الآن ، أليس كذلك؟ الآن لدينا متغير سلسلة S1 تم نقله إلى وظيفة ، والتي تتوقع كائن. هل نحتاج إلى إلقاءها؟ ليس على هذا النحو ، هل تعتقد ، لأن الكائن هو نوع من السلسلة. ومع ذلك ، فإننا نفعل - لأن هناك وظيفة أخرى داخل نفس الفئة مع نفس الاسم وتوقيع معلمة مختلف. لذلك نحن بحاجة إلى تحليل الفصل بأكمله لمعرفة ما إذا كانت هناك حاجة إلى فريق عمل أم لا.

5) بشكل عام ، فهذا يعني أننا بحاجة إلى تحليل جميع الفصول المشار إليها في جميع المكتبات بما في ذلك وقت تشغيل Java. حمولة كبيرة من العمل! في الواقع ، تم تنفيذ هذه الميزة في بعض إصدار ألفا من Fernflower ، ولكنها لم تصل إلى الإنتاج بعد بسبب الأداء وعقوبة الذاكرة. غيرها من decompilers تفتقر إلى هذه القدرة حسب التصميم.

آمل أن أكون قد أوضحت الأشياء قليلاً :)

يوفر المكون الإضافي Jadclipse Eclipse لإلغاء التجميع أيضًا Decompiler Jode ، والذي قد ترغب في تجربته. أنا استخدمه عندما يستسلم جاد.

كما يستخدم Dava Decompiler السخام الذي - آخر مرة نظرت فيه - كان طموحًا للغاية في إعادة بناء رمز Java الأصلي. لم أحاول مثالك ، لكنك قد ترغب في إلقاء نظرة. http://www.sable.mcgill.ca/dava/

بروكيون يجب التعامل مع استدعاءات الطريقة المحملة بشكل صحيح. مثل Krakatau ، يقوم Procyon بإدراج في البداية لكل وسيطة لا تتطابق مع طريقة الهدف بالضبط. ومع ذلك ، ستتم إزالة معظمها خلال مرحلة لاحقة من فك الإلغاء التي تحدد ويزيل القوالب الزائدة عن الحاجة. سيقوم Procyon بإزالة الطوائف فقط على وسيطات المكالمات إذا كان بإمكانها التحقق من أن القيام بذلك لن يؤدي إلى ربط المكالمة بطريقة مختلفة. على سبيل المثال ، إذا كان .class لا يمكن حل هذه الطريقة ، ولن تحاول إزالة الممثلين على الإطلاق ، لأنه ليس لديه أي وسيلة لمعرفة ما قد تتعارض الأحمال الزائدة.

إضافة إلى الإجابات السابقة: فيما يلي قائمة من decompilers الحديثة اعتبارًا من مارس 2015:

  • بروكيون
  • CFR
  • دينار
  • السرخس

كل منهم يدعمون الطرق الزائدة.

يمكنك اختبار أعلاه ذكر decompilers عبر الإنترنت ، لا مطلوب للتثبيت واتخاذ اختيارك المتعلم الخاص بك. Java Decompilers في السحابة: http://www.javadecompilers.com/

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top