publikaccion publikaccion @publikaccion

jueves, junio 26, 2008

.: Decompilar clases java en linux


Los desarrolladores de java seguramente conozca casi todos el DJ Java Decompiler, que se un programa que nos permite decompilar una clase java ya compilada previamente (los archivos .class de los proyectos java), de modo que obtenemos el código fuente para su modificación, estudio, o comprobación correspondiente.

No sé si este programa funciona con wine, pero no nos va a hacer falta comprobarlo, ya que buscando un poco, di con este programa que funciona igual de bien que el DJ Java Decompiler y que no es otro que Jdec o Java Decompiler.

Java Decompiler (JDec), es un programa que nos da la misma funcionalidad que teníamos con DJ Java Decompiler en Windows con la ventaja de que es código libre y que no requiere de muchos pasos para la instalación correspondiente.

Una vez que hemos descargado el correspondiente tar.gz de sourceforge para JDec lo descomprimimos en un directorio que nos interese, cambiamos los permisos y ya lo podemos ejecutar


$ unzip jdec1.2.zip
$ sudo chmod -R +x *
$ ./Jdec-UI.sh &

JDec

Esto nos abrirá una ventana en el que podremos ver el entorno gráfico para proceder a la decompilación de clases java, aunque antes debemos de configurar algunos parámetros de la aplicación como los directorios temporales, los directorios para la creación de LOGs etc... yendo al menú Configuration > Jdec(Decompiler) Configuration.

JDec Configuación

Una vez hayamos configurado el entorno, ya podremos proceder a decompilar yendo al menú File > New Decompiler task en que tendremos varias opciones para proceder a decompilar para obtener el código fuente.

JDec nueva compilación

Un programa muy útil para todos aquellos que programen en java.

Visto en Rubisf's WebBlog.

1 comentario:

Swicher dijo...

Lamento decirlo, pero JDec esta muy verde en comparación a JD-GUI debido a las siguientes ventajas que este ultimo ofrece:
* Portable (un solo archivo ejecutable, no se si dependa o no de la JVM para descompilar).
* Pequeño (al menos en Windows).
* Te permite revisar el código fuente de una aplicación sin necesidad de guardarlo (el código que muestra tiene un coloreado de sintaxis similar a Eclipse, y si se trata de un archivo JAR, hasta te muestra un árbol con todas las clases de la aplicación).
* No hay que preconfigurar nada (a diferencia de JDec).
* Multiplataforma (igual que JDec).
* Descompilacion inmediata.
* Si un archivo JAR contuviera archivos extras (como html, txt, etc), el programa también los extrae (creo que JDec no puede hacer eso).
* Hay veces en que los descompiladores simplemente no pueden procesar ciertos archivos. Eso me paso con una aplicación con la que probé ambos descompiladores, pero cabe decir que el JD-GUI extrajo el bytecode de dicho archivo (al final dejo un ejemplo de que es lo que revela en estos casos) y el JDec simplemente lo omitió.

Como suele ocurrir, no todo es color de rosa con JD-GUI por lo que a continuación paso a dejar algunas contras que descubrí al usar este programa:
* Solo te permite guardar el código fuente dentro de un archivo zip. Si bien a mi realmente no me parece una desventaja, seguramente lo debe ser para aquellos impacientes que quieren guardar el código directamente en una carpeta.
* Puede darse el caso de que si en un "package" existen muchas clases, el programa guardara archivos con nombre repetido. Por ejemplo, digamos que se esta descompilando una aplicación, la cual que tiene un paquete llamado "org.noseque" y este contiene 50 clases. Pues bien, en estos casos es muy probable que al guardar el código, uno de los archivos se llame a.java y haya otro de nombre A.java. Supongo que en Linux no debe haber problemas con esto, pero en Windows no pueden existir ambos archivos en la misma carpeta ya que asume que tienen el mismo nombre (aunque a simple vista no lo parezca).

Y para terminar, a continuación dejo un fragmento de lo que extrae el JD-GUI cuando se topa con un archivo .class "difícil":

// ERROR //
public void run()
{
// Byte code:
// 0: aconst_null
// 1: astore_1
// 2: new 4 java/net/ServerSocket
// 5: dup
// 6: getstatic 10 org/app/a/a:jdField_a_of_type_Int I
// 9: invokespecial 14 java/net/ServerSocket: (I)V
// 12: astore_1
// 13: aconst_null
// 14: astore_2
// 15: aload_1
// 16: invokevirtual 15 java/net/ServerSocket:accept ()Ljava/net/Socket;
// 19: astore_2
[...]
}