Friday, January 21, 2011

Getting Java Class Version using Python

Getting Java class version is actually quite straightforward once we can understand the Java class format. For more information, see this link.

import struct, os, sys

java_versions = {'45.3' : '1.0',
                 '45.3' : '1.2',
                 '46.0' : '1.2',
                 '47.0' : '1.3',
                 '48.0' : '1.4',
                 '49.0' : '1.5',
                 '50.0' : '1.6'}

def __print_error(msg):
    print "Error:", msg
    sys.exit(1)
    
def get_java_version(class_file):
    if not os.path.exists(class_file):
        __print_error(class_file + " doesn't exist")
    
    f = open(class_file, 'rb')
    if (not struct.unpack('!i', f.read(4)) ==
        struct.unpack('!i', '\xca\xfe\xba\xbe')):
        __print_error("Invalid Java class file")
    minor = str(struct.unpack('!H', f.read(2))[0])
    major = str(struct.unpack('!H', f.read(2))[0])
    version = major + "." + minor      
    return java_versions[version]
                         
if __name__ == "__main__":
    if not len(sys.argv) == 2: __print_error("Invalid arguments")
    print get_java_version(sys.argv[1])

The most important thing to note here is that. The first 4 bytes (signed int) is the magic number, the next two bytes (unsigned short) is the minor version, and the next two bytes after that is the major version (unsigned short). This can also be easily coded in Java by using DataInputStream.

No comments:

Post a Comment