Est-il Java Decompiler qui peut correctement décompiler les appels de méthodes surchargées?[fermé]

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

  •  27-09-2019
  •  | 
  •  

Question

Considérez ceci (à mon humble avis simple) exemple:

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

Compiler avec source/cible niveau 1.1 sans les informations de débogage (c'est à direpas de variable locale d'information devrait être présent) et essayer de le décompiler.J'ai essayé de Jad, JD-GUI et Fernflower, et chacun d'eux ont reçu au moins un appel de mal (j'.e.le programme imprimé "Faux!" au moins une fois)

Il n'y a vraiment pas de java decompiler que pouvons en déduire que le droit de moulages, de sorte qu'il n'appellera pas le mal de surcharge?

Edit: Niveau cible 1.1 de sorte qu'il n'y a que Java6-spécifique fast-validation de l'information actuelle.Que pourrait donner l'decompiler un indice que s1 a été déclarée comme Object et pas que String.La décompilation devrait être capable de décompiler le code, même sans cette information (pas nécessairement obtenir l'original de type de variable, mais montrent le même comportement), surtout que beaucoup de obfuscators bande ainsi.

Ce que la décompilation est trompé:

  • Ils ont raté le casting de (Object) dans le premier appel.
  • Ils ont déduit le type de s1 pour être String, mais que vous avez oublié d'ajouter un plâtre à l'appel à doPrint (de sorte que la Chaîne de version est appelée à la place de la version de l'Objet).
  • Une merde (je n'ai même pas répertoriés), même déduit le type de s2 à la Chaîne, provoquant uncompilable code.

En tout cas, ce code n'appelle jamais la String surcharge, mais le code décompilé fait.

Était-ce utile?

La solution

Krakatau gère correctement toutes les méthodes surchargées, même les méthodes surchargées sur les types primitifs, dont la plupart des décompilation se tromper.Il exerce toujours des arguments pour le type exact de la méthode appelée, de sorte que le code peut être plus encombré que nécessaire, mais au moins c'est correct.

Divulgation:Je suis l'auteur de Krakatau.

Autres conseils

Bonjour mihi,

désolé pour la réponse tardive.Je suis la copie de ma réponse à partir de http://www.reversed-java.com/fernflower/forum?threadfolder=2_DE

Votre problème est en réalité bien connue.Voyons voir:

1) Pur bytecode ne contient aucune information sur le type de variables d'objet, de sorte que dans le premier passage de s1 et s2 sont déclarés en tant qu'Objet.

2) Decompiler est un effort d'attribuer le mieux possible le type de chaque variable (= "le plus étroit type de principe", mis en œuvre dans Fernflower).Si s1 et s2 sont correctement identifiés comme des instances de String.

3) l'Invocation de doPrint nous donner un lien direct vers la bonne méthode
private static void doPrint(Objet s1)

4) Tout est OK jusqu'à présent, non?Maintenant nous avons une variable de type String s1 passés à une fonction qui attend un Objet.Avons-nous besoin de le jeter?Pas en tant que tel, on pourrait penser que, comme l'Objet est un super-type de Chaîne.Et pourtant, nous n' - car il existe une autre fonction au sein de la même classe avec le même nom et un autre paramètre de la signature.Nous devons donc analyser l'ensemble de la classe pour savoir, si une distribution est nécessaire ou non.

5) d'une manière générale, cela signifie que nous devons analyser TOUTES référencées classes dans TOUTES les bibliothèques, y compris l'exécution de java.Une énorme charge de travail!En effet, cette fonctionnalité a été implémentée dans certains version alpha de Fernflower, mais n'ont pas fait dans la production, mais en raison de la performance et de la mémoire de la peine.D'autres mentionné la décompilation manque cette capacité par la conception.

Espérons que j'ai clarifié les choses un peu :)

Le JadClipse plugin Eclipse pour la décompilation fournit également la JODE decompiler, que vous pouvez essayer.Je l'utilise quand Jad abandonne.

Aussi le Dava decompiler utilise la Suie qui - la dernière fois que j'ai regardé, était très ambitieux dans la reconstitution de l'original du code Java.Je n'ai pas essayé avec votre exemple, mais vous voudrez peut-être avoir un coup d'oeil. http://www.sable.mcgill.ca/dava/

Procyon doit gérer méthode surchargée invocations correctement.Comme Krakatau, Procyon initialement insère jette pour chaque argument d'une méthode qui ne correspond pas exactement la cible de la méthode.Cependant, la plupart de ceux-ci seront enlevés lors d'une phase ultérieure de la décompilation, qui identifie et élimine redondant jette.Procyon ne supprime jette sur des arguments d'appel si l'on peut vérifier que cela n'entraînera pas dans l'appel de liaison à une méthode différente.Par exemple, si l' .class déclarant que la méthode ne peut pas être résolu, il ne sera pas essayer d'enlever le jette à tous, parce qu'il n'a aucun moyen de savoir ce que les surcharges peuvent entrer en conflit.

Pour ajouter à la réponse à la question précédente:Voici une liste de moderne la décompilation à compter de Mars 2015:

  • Procyon
  • CFR
  • JD
  • Fernflower

Elles prennent TOUTES en charge les méthodes surchargées.

Vous pouvez tester au-dessus de mentionner la décompilation en ligne, aucune installation n'est nécessaire et de faire votre propre choix instruit.Java décompilation dans le cloud: http://www.javadecompilers.com/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top