jreversepro.parser.JAttribute Maven / Gradle / Ivy
/*
@(#)JAttribute.java JReversePro - Java Decompiler / Disassembler.
* Copyright (C) 2000 2001 Karthik Kumar.
* EMail: [email protected]
*
* This program is free software; you can redistribute it and/or modify
* it , under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program.If not, write to
* The Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
package jreversepro.parser;
import jreversepro.reflect.JConstantPool;
import jreversepro.reflect.JMethod;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* JAttribute has the ability to read the 'ATTRIBUTES' of the
* Field , Method and the Class as a whole.
*
* @author Karthik Kumar
* @version 1.00,
*/
public final class JAttribute {
/**
* Code attribute of a Method.
*/
public static final String CODE = "Code";
/**
* ConstantValue attribute of a Method.
*/
public static final String CONSTANT_VALUE = "ConstantValue";
/**
* Deprecated attribute of a Method.
*/
public static final String DEPRECATED = "Deprecated";
/**
* Exceptions attribute of a Method.
*/
public static final String EXCEPTIONS = "Exceptions";
/**
* LineNumberTable attribute of a Method.
*/
public static final String LINENUMBERTABLE = "LineNumberTable";
/**
* LocalVariableTable attribute of a Method.
*/
public static final String LOCALVARIABLETABLE = "LocalVariableTable";
/**
* SourceFile attribute of a Method.
*/
public static final String SOURCEFILE = "SourceFile";
/**
* Synthetic attribute of a Method.
*/
public static final String SYNTHETIC = "Synthetic";
/**
* Manipulates the 'Code' attribute of the Methods.
*
* Code attribute
* u2 attribute_name_index;
* u4 attribute_length;
* u2 max_stack;
* u2 max_locals;
* u4 code_length;
* u1 code[code_length];
* u2 exception_table_length;
* {
* u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type;
* } exception_table[exception_table_length];
* u2 attributes_count;
* attribute_info attributes[attributes_count];
*
* @param aDis DataInputStream containing the bytes of the class.
* @param aCpInfo ConstantPool Information.
* @param aLocalMethod Reference to the current method for which the code
* is to be manipulated.
* @throws IOException Error in Class Stream of bytes.
*/
public static void manipCode(DataInputStream aDis, JMethod aLocalMethod, JConstantPool aCpInfo)
throws IOException {
int len = aDis.readInt();
//Attribute length
short maxStack = aDis.readShort();
aLocalMethod.setMaxStack(maxStack);
short maxLocals = aDis.readShort();
aLocalMethod.setMaxLocals(maxLocals);
int codeLen = aDis.readInt();
byte[] btArray = new byte[codeLen];
aDis.readFully(btArray);
aLocalMethod.setBytes(btArray);
short excLen = aDis.readShort();
for (int i = 0; i < excLen; i++) {
short startPc = aDis.readShort();
short endPc = aDis.readShort();
short handlerPc = aDis.readShort();
short catchType = aDis.readShort();
//If type of class caught is any, then CatchType is 0.
aLocalMethod.addExceptionBlock(startPc, endPc, handlerPc, aCpInfo.getClassName(catchType));
}
short attrCount = aDis.readShort();
for (int i = 0; i < attrCount; i++) {
readCodeAttributes(aDis, aCpInfo);
}
}
/**
* Reads the possible attributes of Code.
*
* Possible attributes of Code are
* LineNumberTable and LocalVariableTable
*
* @param aDis DataInputStream containing the bytes of the class.
* @param aCpInfo ConstantPool Information.
* @throws IOException Error in Class Stream of bytes.
*/
private static void readCodeAttributes(DataInputStream aDis, JConstantPool aCpInfo)
throws IOException {
short attrNameIndex = aDis.readShort();
String attrName = aCpInfo.getUtf8String(attrNameIndex);
if (attrName.equals(LINENUMBERTABLE)) {
manipLineNumberTable(aDis);
} else if (attrName.equals(LOCALVARIABLETABLE)) {
manipLocalVariableTable(aDis);
}
}
/**
* Manipulates the LineNumberTable attribute.
*
* LineNumberTable_attribute
* u2 attribute_name_index;
* u4 attribute_length;
* u2 line_number_table_length; {
* u2 start_pc;
* u2 line_number;
* } line_number_table[line_number_table_length];
*
* @param aDis DataInputStream containing the bytes of the class.
* @throws IOException Error in Class Stream of bytes.
*/
private static void manipLineNumberTable(DataInputStream aDis)
throws IOException {
int len = aDis.readInt();
byte[] btRead = new byte[len];
//TODONew: Do some manipulation with the LineNumberTable
// attribute..
aDis.readFully(btRead);
}
/**
* Manipulates the LocalVariableTable attribute.
*
* LocalVariableTable_attribute
* u2 local_variable_table_length;
* {
u2 start_pc;
* u2 length;
* u2 name_index;
* u2 descriptor_index;
* u2 index;
* } local_variable_table[local_variable_table_length];
* u2 attribute_name_index;
* u4 attribute_length;
* u2 line_number_table_length; {
* u2 start_pc;
* u2 line_number;
* } line_number_table[line_number_table_length];
*
* @param aDis DataInputStream containing the bytes of the class.
* @throws IOException Error in Class Stream of bytes.
*/
private static void manipLocalVariableTable(DataInputStream aDis)
throws IOException {
int len = aDis.readInt();
byte[] btRead = new byte[len];
aDis.readFully(btRead);
}
/**
* Manipulates the 'ConstantValue' attribute of the Fields.
*
* ConstantValue attribute
* u2 attribute_name_index;
* u4 attribute_length;
* u2 constantvalue_index;
*
* @param aDis DataInputStream containing the bytes of the class.
* @param aCpInfo ConstantPool Information.
* @return a String containing the Constant value, of the field.
* @throws IOException Error in Class Stream of bytes.
* @throws ClassParserException Thrown in case of any wrong
* constantpool reference.
*/
public static String manipConstantValue(DataInputStream aDis, JConstantPool aCpInfo)
throws IOException, ClassParserException {
int len = aDis.readInt();
short index = aDis.readShort();
return (aCpInfo.getBasicDataTypeValue(index));
}
/**
* Manipulates the 'Deprecated' attribute of the Fields.
*
* Deprecated attribute
* u2 attribute_name_index;
* u4 attribute_length;
*
* @param aDis DataInputStream containing the bytes of the class.
* @throws IOException Error in Class Stream of bytes.
*/
public static void manipDeprecated(DataInputStream aDis)
throws IOException {
int len = aDis.readInt();//len must be zero.
}
/**
* Manipulates the Exceptions attribute.
*
* Exceptions_attribute
* u2 attribute_name_index;
* u4 attribute_length;
* u2 number_of_exceptions;
* u2 exception_index_table[number_of_exceptions];
*
* Present , if there is a throws clause in the declaration of
* the method.
*
* @param aDis DataInputStream containing the bytes of the class.
* @param aCpInfo ConstantPool Information.
* @return Set of classes present in the 'throws' clause statement.
* @throws IOException Error in Class Stream of bytes.
*/
public static List manipExceptions(DataInputStream aDis, JConstantPool aCpInfo)
throws IOException {
//Responsible for the 'throws' clause
List classes = new ArrayList<>(2);
aDis.readInt();
short numException = aDis.readShort();
for (int i = 0; i < numException; i++) {
short classIndex = aDis.readShort();
classes.add(aCpInfo.getClassName(classIndex));
}
return classes;
}
/**
* Manipulates the 'SourceFile' attribute of the Fields.
*
* SourceFile attribute
* u2 attribute_name_index;
* u4 attribute_length;
* u2 sourcefile_index;
*
* @param aDis DataInputStream containing the bytes of the class.
* @param aCpInfo ConstantPool Information.
* @return NO_STRING
* @throws IOException Error in Class Stream of bytes.
*/
public static String manipSourceFile(DataInputStream aDis, JConstantPool aCpInfo)
throws IOException {
aDis.readInt();
short srcIndex = aDis.readShort();
return aCpInfo.getUtf8String(srcIndex);
}
/**
* Manipulates the 'Synthetic' attribute of the Fields.
*
* Synthetic attribute
* u2 attribute_name_index;
* u4 attribute_length;
*
* @param aDis DataInputStream containing the bytes of the class.
* @throws IOException Error in Class Stream of bytes.
*/
public static void manipSynthetic(DataInputStream aDis)
throws IOException {
int len = aDis.readInt();//len must be zero.
}
}