数组协变带来的静态类型漏洞2011-10-07 javaeye RednaxelaFX在刚才一个通不过Java字节码校验的例子里,我们看到JVM会对其所加载的.class文件做校验,以保证 类型安全。但Java里有这么一种情况,是编译器和JVM的字节码校验都无法检测到,而要到实际运行的时 候才能发现的错误——数组的协变导致的类型静态系统漏洞。还是像前一帖一样,用ASM来生成字节码:Java代码
import java.io.FileOutputStream;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;public class TestASM implements Opcodes {public static void main(String[] args) throws Exception {ClassWriter cw = new ClassWriter(0);cw.visit(V1_5, // class format versionACC_PUBLIC, // class modifiers"TestVerification", // class name fully qualified namenull, // generic signature"java/lang/Object", // super class fully qualified namenew String[] { }// implemented interfaces);MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, // access modifiers"main",// method name "([Ljava/lang/String;)V", // method description null, // generic signature null// exceptions);mv.visitCode();mv.visitInsn(ICONST_1);mv.visitTypeInsn(ANEWARRAY, "java/lang/Float");mv.visitTypeInsn(CHECKCAST, "[Ljava/lang/Object;");mv.visitVarInsn(ASTORE, 0);mv.visitVarInsn(ALOAD, 0);mv.visitInsn(ICONST_0);mv.visitLdcInsn("a string");mv.visitInsn(AASTORE);mv.visitVarInsn(ALOAD, 0);mv.visitInsn(ICONST_0);mv.visitInsn(AALOAD);mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()V");mv.visitInsn(RETURN);mv.visitMaxs(3, 1);mv.visitEnd(); // end methodcw.visitEnd(); // end classbyte[] clz = cw.toByteArray();FileOutputStream out = new FileOutputStream("TestVerification.class");out.write(clz);out.close();}}