9
votes

Y a-t-il un décompiler Java qui peut corriger correctement les appels à des méthodes surchargées?

Considérez cet exemple (IMHO 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 + " ");
    }
}


1 commentaires

Que voulez-vous dire "ils ont eu l'appel faux"? Quelle source génère-t-elle après avoir décompilé?


5 Réponses :


3
votes

Le plug-in Jadclipse Eclipse pour décompilation fournit également le décompiler Jode, que vous voudrez peut-être 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 reconstruction du code Java d'origine. Je n'ai pas essayé avec votre exemple, mais vous voudrez peut-être jeter un coup d'œil. http://www.sable.mcgill.ca/dava/


3 commentaires

Dava a échoué comme les autres. Jode a travaillé, mais puisque Jode a tendance à s'écraser sur presque tous les programmes qui ont traversé n'importe quel Obfuscator, cela ne m'aidait pas vraiment :( suppose que j'ai posé la mauvaise question.;)


Downvote et accepte la réponse? C'était nouveau :)


a changé ma réponse acceptée si vous n'aimez pas être évité et accepté :) (Je vous ai révélé pour la première fois que vos suggestions ne fonctionnaient pas non plus, non plus que de toutes les réponses bientvées, c'était le meilleur) - BTW Où pouvez-vous voir cela Était-ce moi qui a tous deux descendu et accepté?



9
votes

hallo mihi,

Désolé pour la réponse tardive. Je copie ma réponse depuis http://www.reversed-java.com/ Fernflower / Forum? Filfolder = 2_de

Votre problème est en fait un bien connu. Voyons:

1) pure bytecode ne contient aucune information sur le type de variables d'objet, de sorte que dans la première passe S1 et S2 sont déclarés comme objet.

2) Decompiler essaie d'affecter le meilleur type possible à chaque variable (= "principe de type le plus étroit" implémenté dans Fernflower). SO S1 et S2 sont donc correctement identifiés comme des instances de chaîne.

3) Invocation de DOPRINT Donnez-nous un lien direct vers la méthode correcte
DOPRINT VOID STATIQUE privé (objet S1)

4) tout va bien jusqu'à présent, non? Nous avons maintenant une variable de chaîne S1 passée à une fonction, ce qui attend un objet. Avons-nous besoin de le jeter? Pas en tant que tel, vous penseriez que l'objet est un super type de chaîne. Et pourtant, nous faisons - car il y a une autre fonction dans la même classe avec le même nom et une signature de paramètres différente. Nous devons donc analyser toute la classe pour savoir si une distribution est nécessaire ou non.

5) De manière générale, cela signifie que nous devons analyser toutes les classes référencées dans toutes les bibliothèques, y compris le temps d'exécution Java. Une énorme charge de travail! En effet, cette fonctionnalité a été mise en œuvre dans une version alpha de FernLeflower, mais ne l'a pas encore fait dans la production à cause de la pénalité de performance et de mémoire. D'autres décompileurs mentionnés n'ont pas cette capacité de conception.

J'espère avoir des choses clarifiées un peu :)


4 commentaires

Oui, je connais le problème général (c'est pourquoi il n'était pas difficile pour moi de réduire une classe beaucoup plus longue à l'échantillon ci-dessus). Mais, si je comprends bien, si vous n'avez pas d'informations de classe sur la classe cible, vous pouvez toujours ajouter une extinction (superflu) sur le type exact du paramètre, ne pouvez-vous pas? Vous pouvez toujours utiliser le Quickfix d'Eclipse pour supprimer toutes les coudes superflues plus tard. (i. e. Je préférerais la correction de la beauté lorsque le code de décompilation)


Vous avez raison, cela pourrait être fait. Le seul inconvénient serait que nous générons un code très laid avec toutes ces moulages inutiles. Je vais mettre en œuvre une option pour ce comportement, merci pour la suggestion.


"Pure Bytecode ne contient aucune information sur le type de variables d'objet"


"Pure Bytecode ne contient aucune information sur le type de variables d'objet" - mal. Les types sont dérivés de sources de données dactylographiques (arguments, champs) et d'appels d'opérations et de méthodes (tous tous sont dactylographiés). Les attributs de carte de cheminement sont également fournis aux codes de méthode. De plus, le vérificateur de bytecode empêche le chargement des camarades de classe avec des variables locales correctement dactylographiées.



5
votes

Krakatau gère correctement toutes les méthodes surchargées, même les méthodes surchargées sur des types primitifs, ce qui se trompe. Il jette toujours des arguments sur le type exact de la méthode appelée, de sorte que le code peut être plus encombré que nécessaire, mais au moins il est correct.

Divulgation: je suis l'auteur de Krakatau.


0 commentaires

3
votes

procyon doit gérer correctement les invocations de méthode surchargées. Comme Krakatau, Procyon insère initialement des moulages pour chaque argument de méthode qui ne correspond pas exactement à la méthode cible. Cependant, la plupart d'entre eux seront supprimés au cours d'une phase ultérieure de la décompilation qui identifie et élimine les moulages redondants. Procyon supprimera uniquement les moulages sur les arguments d'appel si elle peut vérifier que cela ne conduira pas à la liaison de l'appel à une méthode différente. Par exemple, si le .Class déclarant que la méthode ne peut pas être résolue, il ne tentera pas de supprimer le tout, car il n'a aucun moyen de savoir quelles surcharges pourraient en conflit.


0 commentaires

1
votes

Ajout aux réponses précédentes: Voici une liste de décompileurs modernes en mars 2015:

  • procyon
  • CFR
  • JD
  • Fernflower

    tous prennent en charge les méthodes surchargées.

    Vous pouvez tester au-dessus de la mention des décompileurs en ligne, aucune installation requise et apporter votre propre choix éduqué. Java Decompilers dans le nuage: http://www.javadecompilers.com/


2 commentaires

Je ne sais pas si JD et JDCore sont les mêmes, mais pour le record: JDCore de ce site interdit de décompiler l'échantillon de cette question


JD et JDCORE sont les mêmes. C'est mauvais qu'il a échoué. J'espère que d'autres compilateurs ont réussi?