1 package jp.igapyon.jcfa;
\r
3 import java.io.IOException;
\r
5 import jp.igapyon.jcfa.util.JcfaUtil;
\r
7 import org.apache.bcel.Constants;
\r
9 * Apache Jakarta BCELを用いたクラスファイル(バイトコード)解析サンプル
\r
11 import org.apache.bcel.classfile.ClassFormatException;
\r
12 import org.apache.bcel.classfile.ClassParser;
\r
13 import org.apache.bcel.classfile.Code;
\r
14 import org.apache.bcel.classfile.Field;
\r
15 import org.apache.bcel.classfile.JavaClass;
\r
16 import org.apache.bcel.classfile.Method;
\r
18 public class JavaClassFileAnalyzer {
\r
19 private static final String CLASS_MODULE = "./bin/test/TestJavaClass001.class";
\r
21 public static final void main(final String[] args) {
\r
22 new JavaClassFileAnalyzer().process();
\r
25 private final void process() {
\r
27 final JavaClass jc = new ClassParser(CLASS_MODULE).parse();
\r
28 System.out.println("Classname : " + jc.getClassName());
\r
29 System.out.println("Parent class: " + jc.getSuperclassName());
\r
35 } catch (ClassFormatException e) {
\r
36 e.printStackTrace();
\r
37 } catch (IOException e) {
\r
38 e.printStackTrace();
\r
42 private void analyzeFields(final JavaClass jc) {
\r
43 final org.apache.bcel.classfile.Field[] fields = jc.getFields();
\r
44 for (int indexField = 0; indexField < fields.length; indexField++) {
\r
45 final Field field = fields[indexField];
\r
46 System.out.println(" Field:" + field.getName());
\r
48 access += field.isPublic() ? "public " : "";
\r
49 access += field.isAbstract() ? "abstract " : "";
\r
50 access += field.isStatic() ? "static " : "";
\r
51 access += field.isFinal() ? "final " : "";
\r
52 System.out.println(" " + access);
\r
53 System.out.println(" " + field.getSignature());
\r
57 private void analyzeMethods(final JavaClass jc) throws IOException {
\r
58 final org.apache.bcel.classfile.Method[] methods = jc.getMethods();
\r
59 for (int indexMethod = 0; indexMethod < methods.length; indexMethod++) {
\r
60 final Method method = methods[indexMethod];
\r
61 System.out.println(" Method:" + method.getName());
\r
62 final Code code = method.getCode();
\r
67 final byte[] codes = code.getCode();
\r
68 for (int pc = 0; pc < codes.length; pc++) {
\r
69 final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);
\r
70 short operands = Constants.NO_OF_OPERANDS[opcode];
\r
72 System.out.println(" TODO negative value:"
\r
73 + Constants.OPCODE_NAMES[opcode] + ": " + operands);
\r
78 case Constants.RETURN: {
\r
79 System.out.println(" " + pc + ": "
\r
80 + Constants.OPCODE_NAMES[opcode]);
\r
83 case Constants.GETSTATIC: {
\r
84 System.out.println(" "
\r
87 + Constants.OPCODE_NAMES[opcode]
\r
89 + JcfaUtil.getConstantFieldrefString(jc,
\r
90 codes[pc + 1], codes[pc + 2]));
\r
93 case Constants.LDC: {
\r
94 System.out.println(" " + pc + ": "
\r
95 + Constants.OPCODE_NAMES[opcode] + ": "
\r
96 + JcfaUtil.getConstantString(jc, codes[pc + 1]));
\r
99 case Constants.INVOKEVIRTUAL:
\r
100 case Constants.INVOKESPECIAL: {
\r
101 final int operand = JcfaUtil.byte2UnsignedShort(
\r
102 codes[pc + 1], codes[pc + 2]);
\r
103 System.out.println(" " + pc + ": "
\r
104 + Constants.OPCODE_NAMES[opcode] + ": "
\r
105 + JcfaUtil.getConstantMethodRefString(jc, operand));
\r
108 case Constants.LOOKUPSWITCH:
\r
109 int result = JcfaUtil.byte2Int(codes[pc + 1],
\r
110 codes[pc + 2], codes[pc + 3], codes[pc + 4]);
\r
111 System.out.println(" TODO skipping bytes: " + (result));
\r
113 int lookupOp = pc + 5;
\r
115 short diff = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
\r
116 System.out.println(" TODO skipping bytes: " + (diff));
\r
118 int loopCount = JcfaUtil.byte2Int(codes[lookupOp++],
\r
119 codes[lookupOp++], codes[lookupOp++],
\r
120 codes[lookupOp++]);
\r
121 for (int index = 0; index < loopCount; index++) {
\r
122 System.out.println(" "
\r
123 + JcfaUtil.byte2Int(codes[lookupOp++],
\r
124 codes[lookupOp++], codes[lookupOp++],
\r
127 + (JcfaUtil.byte2Int(codes[lookupOp++],
\r
128 codes[lookupOp++], codes[lookupOp++],
\r
129 codes[lookupOp++]) + pc));
\r
132 short diff2 = JcfaUtil.byte2UnsignedByte(codes[lookupOp++]);
\r
133 System.out.println(" TODO skipping bytes: " + (diff2));
\r
135 operands += (lookupOp - pc);
\r
139 System.out.println(" " + pc + ": "
\r
140 + Constants.OPCODE_NAMES[opcode] + " (" + operands
\r