OSDN Git Service

Creating new project.
authoriga <tosiki.iga@nifty.ne.jp>
Sun, 30 Mar 2014 12:28:37 +0000 (21:28 +0900)
committeriga <tosiki.iga@nifty.ne.jp>
Sun, 30 Mar 2014 12:28:37 +0000 (21:28 +0900)
jcfa/.classpath
jcfa/src/jp/igapyon/jcfa/JavaClassFileAnalyzer.java [new file with mode: 0644]
jcfa/src/jp/igapyon/jcfa/util/JcfaUtil.java [new file with mode: 0644]
jcfa/testJavaClass/src/test/TestJavaClass001.java [new file with mode: 0644]

index 18d70f0..3814f04 100644 (file)
@@ -1,6 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
        <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="testJavaClass/src"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+       <classpathentry kind="lib" path="lib/bcel-5.2.jar"/>
        <classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/jcfa/src/jp/igapyon/jcfa/JavaClassFileAnalyzer.java b/jcfa/src/jp/igapyon/jcfa/JavaClassFileAnalyzer.java
new file mode 100644 (file)
index 0000000..c2fd3b1
--- /dev/null
@@ -0,0 +1,141 @@
+package jp.igapyon.jcfa;\r
+\r
+import java.io.IOException;\r
+\r
+import jp.igapyon.jcfa.util.JcfaUtil;\r
+\r
+import org.apache.bcel.Constants;\r
+/**\r
+ * Apache Jakarta BCELを用いたクラスファイル(バイトコード)解析サンプル\r
+ */\r
+import org.apache.bcel.classfile.ClassFormatException;\r
+import org.apache.bcel.classfile.ClassParser;\r
+import org.apache.bcel.classfile.Code;\r
+import org.apache.bcel.classfile.JavaClass;\r
+import org.apache.bcel.classfile.Method;\r
+\r
+public class JavaClassFileAnalyzer {\r
+       private static final String CLASS_MODULE = "./bin/test/TestJavaClass001.class";\r
+\r
+       public static final void main(final String[] args) {\r
+               new JavaClassFileAnalyzer().process();\r
+       }\r
+\r
+       private final void process() {\r
+               try {\r
+                       final JavaClass jc = new ClassParser(CLASS_MODULE).parse();\r
+                       System.out.println("Classname   : " + jc.getClassName());\r
+                       System.out.println("Parent class: " + jc.getSuperclassName());\r
+\r
+                       final org.apache.bcel.classfile.Method[] methods = jc.getMethods();\r
+                       for (int indexMethod = 0; indexMethod < methods.length; indexMethod++) {\r
+                               final Method method = methods[indexMethod];\r
+                               System.out.println("  Method:" + method.getName());\r
+                               final Code code = method.getCode();\r
+                               if (code == null) {\r
+                                       continue;\r
+                               }\r
+\r
+                               final byte[] codes = code.getCode();\r
+                               for (int pc = 0; pc < codes.length; pc++) {\r
+                                       final short opcode = JcfaUtil.byte2UnsignedByte(codes[pc]);\r
+                                       short operands = Constants.NO_OF_OPERANDS[opcode];\r
+                                       if (operands < 0) {\r
+                                               System.out.println("  TODO negative value:"\r
+                                                               + Constants.OPCODE_NAMES[opcode] + ": "\r
+                                                               + operands);\r
+                                               // break;\r
+                                       }\r
+\r
+                                       switch (opcode) {\r
+                                       case Constants.RETURN: {\r
+                                               System.out.println("    " + pc + ": "\r
+                                                               + Constants.OPCODE_NAMES[opcode]);\r
+                                               break;\r
+                                       }\r
+                                       case Constants.GETSTATIC: {\r
+                                               System.out.println("    "\r
+                                                               + pc\r
+                                                               + ": "\r
+                                                               + Constants.OPCODE_NAMES[opcode]\r
+                                                               + ": "\r
+                                                               + JcfaUtil.getConstantFieldrefString(jc,\r
+                                                                               codes[pc + 1], codes[pc + 2]));\r
+                                               break;\r
+                                       }\r
+                                       case Constants.LDC: {\r
+                                               System.out\r
+                                                               .println("    "\r
+                                                                               + pc\r
+                                                                               + ": "\r
+                                                                               + Constants.OPCODE_NAMES[opcode]\r
+                                                                               + ": "\r
+                                                                               + JcfaUtil.getConstantString(jc,\r
+                                                                                               codes[pc + 1]));\r
+                                       }\r
+                                               break;\r
+                                       case Constants.INVOKEVIRTUAL:\r
+                                       case Constants.INVOKESPECIAL: {\r
+                                               final int operand = JcfaUtil.byte2UnsignedShort(\r
+                                                               codes[pc + 1], codes[pc + 2]);\r
+                                               System.out.println("    "\r
+                                                               + pc\r
+                                                               + ": "\r
+                                                               + Constants.OPCODE_NAMES[opcode]\r
+                                                               + ": "\r
+                                                               + JcfaUtil.getConstantMethodRefString(jc,\r
+                                                                               operand));\r
+                                       }\r
+                                               break;\r
+                                       case Constants.LOOKUPSWITCH:\r
+                                               int result = JcfaUtil.byte2Int(codes[pc + 1],\r
+                                                               codes[pc + 2], codes[pc + 3], codes[pc + 4]);\r
+                                               System.out\r
+                                                               .println("  TODO skipping bytes: " + (result));\r
+\r
+                                               int lookupOp = pc + 5;\r
+\r
+                                               short diff = JcfaUtil\r
+                                                               .byte2UnsignedByte(codes[lookupOp++]);\r
+                                               System.out.println("  TODO skipping bytes: " + (diff));\r
+\r
+                                               int loopCount = JcfaUtil.byte2Int(codes[lookupOp++],\r
+                                                               codes[lookupOp++], codes[lookupOp++],\r
+                                                               codes[lookupOp++]);\r
+                                               for (int index = 0; index < loopCount; index++) {\r
+                                                       System.out.println("      "\r
+                                                                       + JcfaUtil.byte2Int(codes[lookupOp++],\r
+                                                                                       codes[lookupOp++],\r
+                                                                                       codes[lookupOp++],\r
+                                                                                       codes[lookupOp++])\r
+                                                                       + ":"\r
+                                                                       + (JcfaUtil.byte2Int(codes[lookupOp++],\r
+                                                                                       codes[lookupOp++],\r
+                                                                                       codes[lookupOp++],\r
+                                                                                       codes[lookupOp++]) + pc));\r
+                                               }\r
+\r
+                                               short diff2 = JcfaUtil\r
+                                                               .byte2UnsignedByte(codes[lookupOp++]);\r
+                                               System.out.println("  TODO skipping bytes: " + (diff2));\r
+\r
+                                               operands += (lookupOp - pc);\r
+\r
+                                               break;\r
+                                       default: {\r
+                                               System.out.println("    " + pc + ": "\r
+                                                               + Constants.OPCODE_NAMES[opcode] + " ("\r
+                                                               + operands + ")");\r
+                                       }\r
+                                               break;\r
+                                       }\r
+                                       pc += operands;\r
+                               }\r
+                       }\r
+               } catch (ClassFormatException e) {\r
+                       e.printStackTrace();\r
+               } catch (IOException e) {\r
+                       e.printStackTrace();\r
+               }\r
+       }\r
+}
\ No newline at end of file
diff --git a/jcfa/src/jp/igapyon/jcfa/util/JcfaUtil.java b/jcfa/src/jp/igapyon/jcfa/util/JcfaUtil.java
new file mode 100644 (file)
index 0000000..fb4b5eb
--- /dev/null
@@ -0,0 +1,85 @@
+package jp.igapyon.jcfa.util;\r
+\r
+import java.io.ByteArrayInputStream;\r
+import java.io.DataInputStream;\r
+import java.io.IOException;\r
+\r
+import org.apache.bcel.Constants;\r
+import org.apache.bcel.classfile.ConstantClass;\r
+import org.apache.bcel.classfile.ConstantFieldref;\r
+import org.apache.bcel.classfile.ConstantMethodref;\r
+import org.apache.bcel.classfile.ConstantNameAndType;\r
+import org.apache.bcel.classfile.ConstantPool;\r
+import org.apache.bcel.classfile.ConstantString;\r
+import org.apache.bcel.classfile.ConstantUtf8;\r
+import org.apache.bcel.classfile.JavaClass;\r
+\r
+public class JcfaUtil {\r
+       private JcfaUtil() {\r
+       }\r
+\r
+       public static short byte2UnsignedByte(final byte byte1) {\r
+               short word = byte1;\r
+               if (word < 0) {\r
+                       word += 0x100;\r
+               }\r
+               return word;\r
+       }\r
+\r
+       public static int byte2UnsignedShort(final byte byte1, final byte byte2) {\r
+               short word1 = byte1;\r
+               short word2 = byte2;\r
+               if (word1 < 0) {\r
+                       word1 += 0x100;\r
+               }\r
+               if (word2 < 0) {\r
+                       word2 += 0x100;\r
+               }\r
+               return word1 * 0x100 + word2;\r
+       }\r
+\r
+       public static int byte2Int(final byte byte1, final byte byte2,\r
+                       final byte byte3, final byte byte4) throws IOException {\r
+               return new DataInputStream(new ByteArrayInputStream(new byte[] { byte1,\r
+                               byte2, byte3, byte4 })).readInt();\r
+       }\r
+\r
+       public static String getConstantString(final JavaClass jc,\r
+                       final byte operand) {\r
+               final ConstantPool cp = jc.getConstantPool();\r
+               final ConstantString constRef = (ConstantString) cp.getConstant(\r
+                               JcfaUtil.byte2UnsignedByte(operand), Constants.CONSTANT_String);\r
+               return constRef.getBytes(cp);\r
+       }\r
+\r
+       public static String getConstantFieldrefString(final JavaClass jc,\r
+                       final byte byte1, final byte byte2) {\r
+               final ConstantPool cp = jc.getConstantPool();\r
+               final ConstantFieldref constRef = (ConstantFieldref) cp.getConstant(\r
+                               JcfaUtil.byte2UnsignedShort(byte1, byte2),\r
+                               Constants.CONSTANT_Fieldref);\r
+               final ConstantNameAndType constNameAndTypeUtf8 = (ConstantNameAndType) cp\r
+                               .getConstant(constRef.getNameAndTypeIndex(),\r
+                                               Constants.CONSTANT_NameAndType);\r
+               return constRef.getClass(cp) + "#" + constNameAndTypeUtf8.getName(cp)\r
+                               + " type:" + constNameAndTypeUtf8.getSignature(cp);\r
+       }\r
+\r
+       public static String getConstantMethodRefString(final JavaClass jc,\r
+                       final int operand) {\r
+               final ConstantPool cp = jc.getConstantPool();\r
+               final ConstantMethodref constRef = (ConstantMethodref) cp.getConstant(\r
+                               operand, Constants.CONSTANT_Methodref);\r
+               final ConstantClass constClass = (ConstantClass) cp.getConstant(\r
+                               constRef.getClassIndex(), Constants.CONSTANT_Class);\r
+               final ConstantUtf8 constClassUtf8 = (ConstantUtf8) cp.getConstant(\r
+                               constClass.getNameIndex(), Constants.CONSTANT_Utf8);\r
+               final ConstantNameAndType constNameAndTypeUtf8 = (ConstantNameAndType) cp\r
+                               .getConstant(constRef.getNameAndTypeIndex(),\r
+                                               Constants.CONSTANT_NameAndType);\r
+\r
+               return (constClassUtf8.getBytes() + "#"\r
+                               + constNameAndTypeUtf8.getName(cp) + constNameAndTypeUtf8\r
+                                       .getSignature(cp));\r
+       }\r
+}\r
diff --git a/jcfa/testJavaClass/src/test/TestJavaClass001.java b/jcfa/testJavaClass/src/test/TestJavaClass001.java
new file mode 100644 (file)
index 0000000..fa479e9
--- /dev/null
@@ -0,0 +1,7 @@
+package test;\r
+\r
+public class TestJavaClass001 {\r
+       public static void main(final String[] args) {\r
+               System.out.println("Hello jcfa world!");\r
+       }\r
+}\r