- Usando el comando javap
- Codificando en Java para leer los 8 primeros bytes, usando clases del paquete java.io
4 Bytes | 2 Bytes | 2 Bytes |
Número Mágico | Versión Menor | Versión Mayor |
0xCAFEBABE | {0,3} | {45,46,47,48,49,50} |
11001010111111101011101010111110 | … | … |
Los primeros 4 bytes corresponden a un número único que identifica que el archivo corresponde a un archivo de clase Java, éste número se lo conoce como número mágico y en hexadecimal corresponde al número 0xCAFEBABE.
Los 2 bytes siguientes representan la versión menor y los 2 bytes subsiguientes representan la versión mayor del JDK con el cuál fue compilada la clase. En la siguiente tabla se describen las versiones de la plataforma Java:
Minor Version | Major Version | Java Platform Version | Release Date |
3 | 45 | 1.0 | 23-ENE-1996 |
3 | 45 | 1.1 | 19-FEB-1997 |
0 | 46 | 1.2 | 08-DIC-1998 |
0 | 47 | 1.3 | 08-MAY-2000 |
0 | 48 | 1.4 | 06-FEB-2002 |
0 | 49 | 1.5 | 30-SEP-2004 |
0 | 50 | 1.6 | 11-DIC-2006 |
Para utilizar el comando javap, es necesario abrir la consola de comandos del sistema operativo y ubicarse en dónde se encuentra el archivo de clase compilado, por ejemplo: suponiendo que la clase MiClase.class se encuentre en el paquete com.mypackage, el comando se usaría de la siguiente forma:
javap -verbose MiClase
Y se obtendría el siguiente resultado.
Como se puede observar aquí se muestra los valores de minor version y major version, con los cuáles se pueden identificar con cuál JDK fue compilada la clase.
Código fuente para leer los 8 primeros bytes del archivo de clase
Adicional al comando se podría usar el siguiente code snippet para leer los 8 bytes del archivo de clase Java:
try { String nombreArchivo = "c:\java\src\com\mypackage\MiClase.class"; DataInputStream in = new DataInputStream(new FileInputStream(nombreArchivo)); int numeroMagico = in.readInt(); if (numeroMagico != 0xCAFEBABE) { System.out.println(nombreArchivo + " no es una clase valida..."); } int versionMenor = in.readUnsignedShort(); int versionMayor = in.readUnsignedShort(); System.out.println("major version = " + versionMayor); in.close(); } catch (IOException e) { System.err.println(e); }
Interesante post amigo, al parecer este mecanismo es utilizado en el proceso de desofuscación para verificar las características aceptadas por un jdk en específico.
ResponderEliminar