Gibt es eine Java Decompiler, die können richtig decompile Anrufe zu überladenen Methoden? [geschlossen]

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

  •  27-09-2019
  •  | 
  •  

Frage

Betrachten Sie diese (IMHO einfach) Beispiel:

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 + " ");
    }
}

Compile es mit Quell- / Zielebene 1.1 ohne Debug-Informationen (das heißt keine lokale Variable Informationen sollten vorhanden sein) und versuchen, es zu dekompilieren. Ich habe versucht, Jad, JD-GUI und Fernflower, und alle von ihnen bekam zumindest einer der Anruf falsch (i. E. Das Programm gedruckt „Falsch!“ Mindestens einmal)

Gibt es wirklich keine Java Decompiler, die die richtigen Würfe so folgern kann, dass es die falsche Überlastung nicht angerufen?

Edit: Zielebene 1.1, so dass es keine von dem Java6 spezifischen schnell Validierungsinformationen vorhanden. Das könnte den Decompiler einen Hinweis geben, dass s1 hat als Object und nicht als String erklärt. Decompiler soll (den ursprünglichen Variablentyp nicht unbedingt erhalten, aber das gleiche Verhalten zeigt) Lage sein, den Code auch ohne diese Informationen zu dekompilieren, zumal viele obfuscators es auch abzuzustreifen.

Was Decompiler bekam falsch:

  • Sie verpassten die Besetzung zu (Object) im ersten Aufruf.
  • Sie entnehmen die Art der s1 String zu sein, aber vergessen haben, eine Besetzung auf den Aufruf zu doPrint hinzuzufügen (so dass die String-Version anstelle der Object-Version genannt wird).
  • Eine crappy ein (ich habe noch nicht einmal aufgeführt) auch die Art der s2 folgert String zu sein, uncompilable Code verursacht.

Auf jeden Fall dieser Code nie ruft die String Überlastung, aber der dekompilierten Code getan hat.

War es hilfreich?

Lösung

Krakatau korrekt behandelt alle überladenen Methoden, auch Methoden überlastet auf primitive Typen, die meisten decompilers falsch. Es wirft immer Argumente, um die genaue Art der aufgerufenen Methode, so dass der Code mehr kann als nötig laden werden, aber zumindest ist es richtig.

Disclosure:. Ich bin der Autor des Krakatau

Andere Tipps

Hallo mihi,

sorry für die späte Antwort. Ich bin Kopieren meine Antwort von http://www.reversed-java.com/ fernflower / forum? threadfolder = 2_DE

Ihr Problem ist eigentlich ein gut bekanntes. Mal sehen:

1) Reine Bytecode enthält keine Informationen über die Art der Objektvariablen, so im ersten Durchgang s1 und s2 werden als Objekt deklariert.

2) Decompiler sind bemüht, die bestmögliche Art zu jeder Variablen (= „schmalsten Typ Prinzip“ umgesetzt in Fernflower) zuzuordnen. So s1 und s2 werden als Instanzen von String richtig erkannt.

3) Invocation von DoPrint gibt uns einen direkten Link auf die richtige Methode
Private static void DoPrint (Object s1)

4) Alles in Ordnung so weit, nicht wahr? Jetzt haben wir ein String-Variable s1 an eine Funktion übergeben bekommen, die ein Objekt erwartet. Müssen wir es werfen? Nicht als solche, würden Sie denken, als Objekt ein Super-Typ String ist. Und doch wir tun - weil es eine andere Funktion innerhalb der gleichen Klasse mit dem gleichen Namen und einem anderen Parameter Signatur. Also brauchen wir die ganze Klasse zu analysieren, um herauszufinden, ob ein gegossenes erforderlich ist oder nicht.

5) Im Allgemeinen bedeutet dies, wir alle referenzierten Klassen in allen Bibliotheken, einschließlich der Java-Laufzeit analysieren müssen. Eine große Last von der Arbeit! Tatsächlich wurde diese Funktion in einiger Alpha-Version von Fernflower implementiert, aber nicht in der Produktion noch wegen der Leistung und Speicher Strafe gemacht. Andere erwähnte decompilers fehlt diese Fähigkeit durch Design.

Hope Ich habe klären die Dinge ein wenig:)

Die JadClipse Eclipse-Plugin für dekompiliert bietet auch den JODE Decompiler, die Sie ausprobieren möchten. Ich benutze es, wenn Jad aufgibt.

Auch die Dava Decompiler verwendet Soot, die - letztes Mal, dass ich sah - war sehr ehrgeizig in dem ursprünglichen Java-Code zu rekonstruieren. Ich habe nicht mit Ihrem Beispiel versucht, aber Sie können einen Blick haben wollen. http://www.sable.mcgill.ca/dava/

Procyon sollte überladene Methode Anrufungen richtig handhaben. Wie Krakatau, fügt Procyon zunächst Abgüsse für jede Methode Argument, das nicht exakt mit der Zielmethode entsprechen. die meisten von ihnen werden jedoch während einer späteren Phase der Dekompilierung entfernt werden identifiziert und eliminiert redundante Abgüsse. Procyon nur Abgüsse auf Abruf Argumente entfernen, wenn es, dass so nicht in dem Aufruf eine andere Methode Bindung führt dabei überprüfen kann, wird. Zum Beispiel, wenn die .class die Methode deklarieren kann nicht aufgelöst wird, wird es nicht versuchen, die Abgüsse überhaupt zu entfernen, weil es keine Möglichkeit zu wissen, was man Konflikt hat Überlastungen.

zu den vorherigen Antworten Hinzufügen: Hier ist eine Liste des modernen decompilers ab März 2015:

  • Procyon
  • CFR
  • JD
  • Fernflower

alle von ihnen unterstützen ladenen Methoden.

Sie können sich online über Erwähnung decompilers testen, keine Installation erforderlich und Ihre eigene gebildete Wahl. Java Decompiler in der Cloud: http://www.javadecompilers.com/

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top