private static ClassMember readClassMember(ClassInvestigator ci, ClassInput in) throws IOException { ClassMember member = new ClassMember(ci, in.getU2(), in.getU2(), in.getU2()); int attributeCount = in.getU2(); if (attributeCount != 0) { member.attribute_info = new Attributes(attributeCount); for (int i = 0; i < attributeCount; i++) member.attribute_info.addEntry(new AttributeEntry(in)); } return member; }
private static ConstantPoolEntry getConstant(ClassInput in) throws IOException { ConstantPoolEntry item; int tag; tag = in.readUnsignedByte(); switch (tag) { case VMDescriptor.CONSTANT_Class: case VMDescriptor.CONSTANT_String: item = new CONSTANT_Index_info(tag, in.getU2(), 0); break; case VMDescriptor.CONSTANT_NameAndType: case VMDescriptor.CONSTANT_Fieldref: case VMDescriptor.CONSTANT_Methodref: case VMDescriptor.CONSTANT_InterfaceMethodref: item = new CONSTANT_Index_info(tag, in.getU2(), in.getU2()); break; case VMDescriptor.CONSTANT_Integer: item = new CONSTANT_Integer_info(in.getU4()); break; case VMDescriptor.CONSTANT_Float: item = new CONSTANT_Float_info(in.readFloat()); break; case VMDescriptor.CONSTANT_Long: item = new CONSTANT_Long_info(in.readLong()); break; case VMDescriptor.CONSTANT_Double: item = new CONSTANT_Double_info(in.readDouble()); break; case VMDescriptor.CONSTANT_Utf8: item = new CONSTANT_Utf8_info(in.readUTF()); break; default: throw new ClassFormatError(); } return item; }
private void processCodeAttribute(ClassMember member, AttributeEntry ae) throws IOException { ClassInput ci = new ClassInput(new java.io.ByteArrayInputStream(ae.infoIn)); DataInputUtil.skipFully(ci, 4); // puts us at code_length int len = ci.getU4(); DataInputUtil.skipFully(ci, len); // puts us at exception_table_length int count = ci.getU2(); if (count != 0) DataInputUtil.skipFully(ci, 8 * count); int nonAttrLength = 4 + 4 + len + 2 + (8 * count); // now at attributes count = ci.getU2(); if (count == 0) return; int newCount = count; for (int i = 0; i < count; i++) { int nameIndex = ci.getU2(); String name = nameIndexToString(nameIndex); if (name.equals("LineNumberTable") || name.equals("LocalVariableTable")) newCount--; else System.err.println("ERROR - Unknown code attribute " + name); len = ci.getU4(); DataInputUtil.skipFully(ci, len); } if (newCount != 0) { System.err.println("ERROR - expecting all code attributes to be removed"); System.exit(1); } // this is only coded for all attributes within a Code attribute being removed. byte[] newInfo = new byte[nonAttrLength + 2]; System.arraycopy(ae.infoIn, 0, newInfo, 0, nonAttrLength); // last two bytes are left at 0 which means 0 attributes ae.infoIn = newInfo; }
public static ClassInvestigator load(InputStream is) throws IOException { ClassInput classInput = new ClassInput(is); // Check the header int magic = classInput.getU4(); int minor_version = classInput.getU2(); int major_version = classInput.getU2(); if (magic != VMDescriptor.JAVA_CLASS_FORMAT_MAGIC) throw new ClassFormatError(); // Read in the Constant Pool int constantPoolCount = classInput.getU2(); ClassInvestigator ci = new ClassInvestigator(constantPoolCount); ci.minor_version = minor_version; ci.major_version = major_version; // Yes, index starts at 1, The '0'th constant pool entry // is reserved for the JVM and is not present in the class file. for (int i = 1; i < constantPoolCount; ) { ConstantPoolEntry item = ClassInvestigator.getConstant(classInput); i += ci.addEntry(item.getKey(), item); } // Read in access_flags and class indexes ci.access_flags = classInput.getU2(); ci.this_class = classInput.getU2(); ci.super_class = classInput.getU2(); // interfaces is a simple int array int interfaceCount = classInput.getU2(); if (interfaceCount != 0) { ci.interfaces = new int[interfaceCount]; for (int i = 0; i < interfaceCount; i++) ci.interfaces[i] = classInput.getU2(); } int fieldCount = classInput.getU2(); if (fieldCount != 0) { ci.field_info = new MemberTable(fieldCount); for (int i = 0; i < fieldCount; i++) { ci.field_info.addEntry(readClassMember(ci, classInput)); } } int methodCount = classInput.getU2(); if (methodCount != 0) { ci.method_info = new MemberTable(methodCount); for (int i = 0; i < methodCount; i++) { ci.method_info.addEntry(readClassMember(ci, classInput)); } } int attributeCount = classInput.getU2(); if (attributeCount != 0) { ci.attribute_info = new Attributes(attributeCount); for (int i = 0; i < attributeCount; i++) ci.attribute_info.addEntry(new AttributeEntry(classInput)); } return ci; }