¿Hay alguna Decompiler Java que puede descompilar correctamente las llamadas a métodos sobrecargados? [cerrado]

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

  •  27-09-2019
  •  | 
  •  

Pregunta

Considere esto (francamente sencillo) ejemplo:

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

Compilar con nivel de fuente / destino 1.1 sin información de depuración (es decir, ninguna información variable local debe estar presente) y tratar de descompilarlo. Probé Jad, JD-GUI y Fernflower, y todos ellos dieron al menos una de las mal llamadas (i. E. El programa impreso "incorrecto" al menos una vez)

¿Realmente no hay decompilador Java que pueden inferir los moldes adecuados para que no se llame a la sobrecarga del mal?

Editar Nivel objetivo 1.1 de modo que no hay nada de eso java6-específica de validación rápida presentar la información. Eso podría dar el decompilador un indicio de que s1 ha sido declarado como Object y no como String. Descompiladores debería ser capaz de descompilar el código, incluso sin esta información (no necesariamente obtener el tipo variable original, pero muestran el mismo comportamiento), especialmente desde un montón de ofuscadores tira de él también.

Lo malo descompiladores conseguido:

  • Se perdió el elenco de (Object) en la primera llamada.
  • Se infiere del tipo de s1 ser String, pero se olvidó de agregar un yeso para la llamada a doPrint (de modo que la versión de cadena se llama en lugar de la versión Object).
  • Una una mierda (Ni siquiera he enumerado) incluso infiere el tipo de s2 ser de cadena, causando código uncompilable.

En cualquier caso, este código nunca se llama a la sobrecarga de String, pero el código descompilada hizo.

¿Fue útil?

Solución

Krakatau maneja correctamente todos los métodos sobrecargados, incluso métodos sobrecargados en los tipos primitivos, que la mayoría de descompiladores equivocarse. Siempre arroja argumentos para el tipo exacto del método llamado, por lo que el código puede ser más desordenada de lo necesario, pero al menos es correcta.

Divulgación:. Soy el autor de Krakatau

Otros consejos

Hola mihi,

Lo siento por la respuesta tardía. Estoy copiando mi respuesta de http://www.reversed-java.com/ fernflower / foro? threadfolder = 2_DE

Su problema es en realidad una bien conocida. Vamos a ver:

1) bytecode Pure no contiene ninguna información sobre el tipo de las variables de objeto, por lo que en la primera s1 pase y s2 se declaran como objeto.

2) Decompiler está tratando de asignar el mejor tipo posible a cada variable (= "principio de tipo más estrecho" implementado en Fernflower). Así S1 y S2 están correctamente identificados como casos de cadena.

3) Invocación de doPrint nos dan un enlace directo con el método correcto
private static void doPrint (s1 Objeto)

4) Todo bien hasta ahora, ¿verdad? Ahora tenemos una variable de cadena s1 pasa a una función, que espera un objeto. ¿Necesitamos echarlo? No como tal, se podría pensar, como objetos es un super-tipo de cadena. Y sin embargo, lo que hacemos - porque hay otra función dentro de la misma clase con el mismo nombre y la firma del parámetro diferente. Por lo tanto, es necesario analizar toda la clase para averiguar, si se necesita o no un yeso.

5) En términos generales, esto significa que hay que analizar clases TODO referencia en bibliotecas de todo, incluyendo el tiempo de ejecución de Java. Una enorme carga de trabajo! De hecho, esta característica se implementó en una versión alfa del Fernflower, pero no lo han hecho en la producción sin embargo por el rendimiento y la pena de memoria. Otros descompiladores mencionados carecen de esta capacidad por diseño.

Espero haber aclarado un poco las cosas:)

El plug-in para Eclipse JadClipse descompilación también proporciona la decompilador JODE, que es posible que desee probar. Yo lo uso cuando Jad se da por vencido.

También el decompilador Dava utiliza hollín, que - la última vez que miré - era muy ambiciosa en la reconstrucción del código original de Java. No he probado con su ejemplo, pero puede que desee echar un vistazo. http://www.sable.mcgill.ca/dava/

Procyon debe manejar las llamadas a métodos sobrecargados correctamente. Al igual que Krakatau, Procyon inserta inicialmente moldes para cada argumento método que no coincide exactamente con el método de destino. Sin embargo, la mayoría de éstos serán eliminados durante una fase posterior de la descompilación que identifica y elimina redundante moldes. Procyon sólo eliminará los moldes sobre los argumentos de llamada si se puede verificar que el hacerlo no dará lugar a la unión a un método diferente llamada. Por ejemplo, si el .class declarar el método no se puede resolver, no va a intentar retirar los moldes en absoluto, porque no tiene manera de saber lo que sobrecarga el conflicto fuerza.

Adición a las respuestas anteriores: He aquí una lista de descompiladores modernos a partir de marzo de 2015:

  • Procyon
  • CFR
  • JD
  • Fernflower

Todos soportan métodos sobrecargados.

Se puede probar por encima de descompiladores mención en línea, no requiere instalación y hacer su propia elección consciente y responsable. Java descompiladores en la nube: http://www.javadecompilers.com/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top