SkillAgentSearch skills...

Classfile

Java classfile formatter / decompiler / compiler using python object notation

Install / Use

/learn @joelhockey/Classfile
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

classfile.py

classfile.py is a java class file formatter / decompiler / compiler that transforms between binary java class files and a python object graph (dicts and arrays).

classfile can be used as a python module or run as a script.

usage:
  classfile.py -d <classfile>
  classfile.py -c <pyobjfile> <classfile>

Why

The JVM is a great piece of technology, but I prefer not to use the Java language. classfile.py makes it possible to view and manipulate class files in python.

More Info

Info about the java class file format at:

  • http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html
  • http://jcp.org/aboutJava/communityprocess/final/jsr202/index.html

Supported Features

Round tripping should work for any class file. There are some class file attributes that are not yet supported, but when these are encountered, the attributes are written in binary format and can be read back from binary format.

Example

Start with a Java source file or class file:

public class Example {
    private static String foo = "world";
    public static void main(String[] args) {
        int times = 2;
        for (int i = 0; i < times; i++) {
            System.out.println("hello " + foo);
        }
    }
}

Compile and Run:

$ javac Example.java
$ java Example
hello world
hello world

Now use classfile to decompile:

$ ./classfile.py -d Example.class > Example.py

This will show the contents of the classfile as a python object:

{'01_magic': 'cafebabe',
 '02_minor_version': 0,
 '03_major_version': 50,
 '04_constant_pool_count': 57,
 '05_cp_info': [{'00_index': 0,
                 '00_tag_name': 'unusable at start to get numbering working',
                 '01_tag': 0},
                {'00_index': 1,
                 '00_tag_name': 'CONSTANT_Class',
                 '01_tag': 7,
                 '02_name_index': 2},
                {'00_index': 2,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 7,
                 '03_bytes': 'Example'},
                {'00_index': 3,
                 '00_tag_name': 'CONSTANT_Class',
                 '01_tag': 7,
                 '02_name_index': 4},
                {'00_index': 4,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 16,
                 '03_bytes': 'java/lang/Object'},
                {'00_index': 5,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 3,
                 '03_bytes': 'foo'},
                {'00_index': 6,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 18,
                 '03_bytes': 'Ljava/lang/String;'},
                {'00_index': 7,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 8,
                 '03_bytes': '<clinit>'},
                {'00_index': 8,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 3,
                 '03_bytes': '()V'},
                {'00_index': 9,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 4,
                 '03_bytes': 'Code'},
                {'00_index': 10,
                 '00_tag_name': 'CONSTANT_String',
                 '00_value': 'world',
                 '01_tag': 8,
                 '02_string_index': 11},
                {'00_index': 11,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 5,
                 '03_bytes': 'world'},
                {'00_index': 12,
                 '00_tag_name': 'CONSTANT_Fieldref',
                 '01_tag': 9,
                 '02_class_index': 1,
                 '03_name_and_type_index': 13},
                {'00_index': 13,
                 '00_tag_name': 'CONSTANT_NameAndType',
                 '01_tag': 12,
                 '02_name_index': 5,
                 '03_descriptor_index': 6},
                {'00_index': 14,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 15,
                 '03_bytes': 'LineNumberTable'},
                {'00_index': 15,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 18,
                 '03_bytes': 'LocalVariableTable'},
                {'00_index': 16,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 6,
                 '03_bytes': '<init>'},
                {'00_index': 17,
                 '00_tag_name': 'CONSTANT_Methodref',
                 '01_tag': 10,
                 '02_class_index': 3,
                 '03_name_and_type_index': 18},
                {'00_index': 18,
                 '00_tag_name': 'CONSTANT_NameAndType',
                 '01_tag': 12,
                 '02_name_index': 16,
                 '03_descriptor_index': 8},
                {'00_index': 19,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 4,
                 '03_bytes': 'this'},
                {'00_index': 20,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 9,
                 '03_bytes': 'LExample;'},
                {'00_index': 21,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 4,
                 '03_bytes': 'main'},
                {'00_index': 22,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 22,
                 '03_bytes': '([Ljava/lang/String;)V'},
                {'00_index': 23,
                 '00_tag_name': 'CONSTANT_Fieldref',
                 '01_tag': 9,
                 '02_class_index': 24,
                 '03_name_and_type_index': 26},
                {'00_index': 24,
                 '00_tag_name': 'CONSTANT_Class',
                 '01_tag': 7,
                 '02_name_index': 25},
                {'00_index': 25,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 16,
                 '03_bytes': 'java/lang/System'},
                {'00_index': 26,
                 '00_tag_name': 'CONSTANT_NameAndType',
                 '01_tag': 12,
                 '02_name_index': 27,
                 '03_descriptor_index': 28},
                {'00_index': 27,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 3,
                 '03_bytes': 'out'},
                {'00_index': 28,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 21,
                 '03_bytes': 'Ljava/io/PrintStream;'},
                {'00_index': 29,
                 '00_tag_name': 'CONSTANT_Class',
                 '01_tag': 7,
                 '02_name_index': 30},
                {'00_index': 30,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 23,
                 '03_bytes': 'java/lang/StringBuilder'},
                {'00_index': 31,
                 '00_tag_name': 'CONSTANT_String',
                 '00_value': 'hello ',
                 '01_tag': 8,
                 '02_string_index': 32},
                {'00_index': 32,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 6,
                 '03_bytes': 'hello '},
                {'00_index': 33,
                 '00_tag_name': 'CONSTANT_Methodref',
                 '01_tag': 10,
                 '02_class_index': 29,
                 '03_name_and_type_index': 34},
                {'00_index': 34,
                 '00_tag_name': 'CONSTANT_NameAndType',
                 '01_tag': 12,
                 '02_name_index': 16,
                 '03_descriptor_index': 35},
                {'00_index': 35,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 21,
                 '03_bytes': '(Ljava/lang/String;)V'},
                {'00_index': 36,
                 '00_tag_name': 'CONSTANT_Methodref',
                 '01_tag': 10,
                 '02_class_index': 29,
                 '03_name_and_type_index': 37},
                {'00_index': 37,
                 '00_tag_name': 'CONSTANT_NameAndType',
                 '01_tag': 12,
                 '02_name_index': 38,
                 '03_descriptor_index': 39},
                {'00_index': 38,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 6,
                 '03_bytes': 'append'},
                {'00_index': 39,
                 '00_tag_name': 'CONSTANT_Utf8',
                 '01_tag': 1,
                 '02_length': 45,
                 '03_bytes': '(Ljava/l
View on GitHub
GitHub Stars8
CategoryDevelopment
Updated1y ago
Forks3

Languages

Python

Security Score

70/100

Audited on Feb 13, 2025

No findings