📄 javaclassparser.java
字号:
/*
* Author jyang Created on 2006-4-2 21:18:16
*/
package com.jasml.decompiler;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import com.jasml.classes.Attribute;
import com.jasml.classes.Attribute_Code;
import com.jasml.classes.Attribute_ConstantValue;
import com.jasml.classes.Attribute_Deprecated;
import com.jasml.classes.Attribute_Exceptions;
import com.jasml.classes.Attribute_InnerClasses;
import com.jasml.classes.Attribute_LineNumberTable;
import com.jasml.classes.Attribute_LocalVariableTable;
import com.jasml.classes.Attribute_SourceFile;
import com.jasml.classes.Attribute_Synthetic;
import com.jasml.classes.ConstantPool;
import com.jasml.classes.ConstantPoolItem;
import com.jasml.classes.Constant_Class;
import com.jasml.classes.Constant_Double;
import com.jasml.classes.Constant_Fieldref;
import com.jasml.classes.Constant_Float;
import com.jasml.classes.Constant_Integer;
import com.jasml.classes.Constant_InterfaceMethodref;
import com.jasml.classes.Constant_Long;
import com.jasml.classes.Constant_Methodref;
import com.jasml.classes.Constant_NameAndType;
import com.jasml.classes.Constant_String;
import com.jasml.classes.Constant_Utf8;
import com.jasml.classes.Constants;
import com.jasml.classes.Field;
import com.jasml.classes.JavaClass;
import com.jasml.classes.Method;
import com.jasml.helper.OpcodeHelper;
import com.jasml.helper.OpcodeInfo;
import com.jasml.helper.Util;
public class JavaClassParser {
DataInputStream in;
int magic;
int minor_Version;
int major_Version;
short constant_Pool_Count;
ConstantPool constantPool;
short access_flags;
int this_class;
int super_class;
int interfaces_count;
// the array storing interface indexes into constant pool
int[] interfaces;
int fields_count;
Field[] fields;
int methods_count;
Method[] methods;
int attributes_count;
Attribute[] attributes;
public JavaClass parseClass(File classFile) throws IOException {
JavaClass ret = null;
try {
FileInputStream fsin = new FileInputStream(classFile);
in = new DataInputStream(fsin);
readMagic();
readVersion();
readConstant_Pool_Count();
readConstantPool();
// prt(constantPool); //
readAccess_flags();
readThis_class();
readSuper_class();
readInterfaces();
readFields();
readMethods();
readAttributes();
ret = new JavaClass();
ret.magic = magic;
ret.minor_version = minor_Version;
ret.major_version = major_Version;
ret.constant_pool_count = constant_Pool_Count;
ret.constantPool = constantPool;
ret.access_flags = access_flags;
ret.this_class = this_class;
ret.super_class = super_class;
ret.interfaces_count = interfaces_count;
ret.interfaces = interfaces;
ret.fields_count = fields_count;
ret.fields = fields;
ret.methods_count = methods_count;
ret.methods = methods;
ret.attributes_count = attributes_count;
ret.attributes = attributes;
} finally {
try {
in.close();
} catch (Exception e) {
}
}
return ret;
}
private void readMagic() throws IOException {
prt("#magic");
magic = in.readInt();
}
private void readVersion() throws IOException {
prt("#version");
minor_Version = in.readUnsignedShort();
major_Version = in.readUnsignedShort();
}
private void readConstant_Pool_Count() throws IOException {
prt("#constant pool");
constant_Pool_Count = (short) in.readUnsignedShort();
}
private void readConstantPool() throws IOException {
ConstantPoolItem[] items = new ConstantPoolItem[constant_Pool_Count];
byte tag;
for (int i = 1; i < constant_Pool_Count; i++) {
tag = in.readByte();
switch (tag) {
case Constants.CONSTANT_Class:
items[i] = new Constant_Class(in.readUnsignedShort());
break;
case Constants.CONSTANT_Fieldref:
items[i] = new Constant_Fieldref(in.readUnsignedShort(), in.readUnsignedShort());
break;
case Constants.CONSTANT_Methodref:
items[i] = new Constant_Methodref(in.readUnsignedShort(), in.readUnsignedShort());
break;
case Constants.CONSTANT_InterfaceMethodref:
items[i] = new Constant_InterfaceMethodref(in.readUnsignedShort(), in.readUnsignedShort());
break;
case Constants.CONSTANT_String:
items[i] = new Constant_String(in.readUnsignedShort());
break;
case Constants.CONSTANT_Integer:
items[i] = new Constant_Integer(in.readInt());
break;
case Constants.CONSTANT_Float:
items[i] = new Constant_Float(in.readFloat());
break;
case Constants.CONSTANT_Long:
items[i] = new Constant_Long(in.readLong());
i++;
break;
case Constants.CONSTANT_Double:
items[i] = new Constant_Double(in.readDouble());
i++;
break;
case Constants.CONSTANT_NameAndType:
items[i] = new Constant_NameAndType(in.readUnsignedShort(), in.readUnsignedShort());
break;
case Constants.CONSTANT_Utf8:
items[i] = new Constant_Utf8(in.readUTF());
break;
default:
throw new IOException("Error inputing class file, unexpected tag:" + tag + ". i = " + i);
}
}
constantPool = new ConstantPool(items);
}
private void readAccess_flags() throws IOException {
access_flags = (short) in.readUnsignedShort();
}
private void readThis_class() throws IOException {
this_class = in.readUnsignedShort();
}
private void readSuper_class() throws IOException {
super_class = in.readUnsignedShort();
}
private void readInterfaces() throws IOException {
prt("#interfaces");
interfaces_count = in.readUnsignedShort();
if (interfaces_count != 0) {
interfaces = new int[interfaces_count];
for (int i = 0; i < interfaces_count; i++) {
interfaces[i] = in.readUnsignedShort();
}
}
}
private void readFields() throws IOException {
prt("#fields");
fields_count = in.readUnsignedShort();
if (fields_count != 0) {
fields = new Field[fields_count];
for (int i = 0; i < fields_count; i++) {
prt("#field :" + i);
fields[i] = readField(in);
}
}
}
private void readMethods() throws IOException {
prt("#methods");
methods_count = in.readUnsignedShort();
if (methods_count != 0) {
methods = new Method[methods_count];
for (int i = 0; i < methods_count; i++) {
methods[i] = readMethod(in);
}
}
}
private void readAttributes() throws IOException {
prt("#class attributes");
attributes_count = in.readUnsignedShort();
if (attributes_count != 0) {
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
prt("#class attribute :" + i);
attributes[i] = readAttribute(in);
}
}
}
private Field readField(DataInputStream in) throws IOException {
int access_flags = in.readUnsignedShort();
int name_index = in.readUnsignedShort();
int descriptor_index = in.readUnsignedShort();
int attributes_count = in.readUnsignedShort();
Attribute[] attributes = null;
if (attributes_count != 0) {
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = readAttribute(in);
}
}
return new Field(access_flags, name_index, descriptor_index, attributes_count, attributes);
}
private Method readMethod(DataInputStream in) throws IOException {
int access_flags = in.readUnsignedShort();
int name_index = in.readUnsignedShort();
int descriptor_index = in.readUnsignedShort();
int attributes_count = in.readUnsignedShort();
prt("#method :" + constantPool.getConstant(name_index));
Attribute[] attributes = null;
if (attributes_count != 0) {
attributes = new Attribute[attributes_count];
for (int i = 0; i < attributes_count; i++) {
attributes[i] = readAttribute(in);
}
}
return new Method(access_flags, name_index, descriptor_index, attributes_count, attributes);
}
private Attribute readAttribute(DataInputStream in) throws IOException {
prt("#Attribute");
Attribute attribute = null;
int attribute_name_index = in.readUnsignedShort();
int attribute_length = in.readInt();
String attribute_name = ((Constant_Utf8) constantPool.getConstant(attribute_name_index)).bytes;
int i = 0;
// get the attribute names
for (; i < Constants.ATTRIBUTE_NAMES.length; i++) {
if (attribute_name.equals(Constants.ATTRIBUTE_NAMES[i]) == true) {
break;
}
}
if (i != Constants.ATTRIBUTE_NAMES.length) {
// known attribute
switch (i) {
case Constants.ATTRIBUTE_SourceFile:
attribute = new Attribute_SourceFile(attribute_length, in.readUnsignedShort());
break;
case Constants.ATTRIBUTE_ConstantValue:
attribute = new Attribute_ConstantValue(attribute_length, in.readUnsignedShort());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -