1 16 package net.sf.cglib.transform.hook; 17 18 import java.io.*; 19 import net.sf.cglib.core.RemappingCodeVisitor; 20 import org.codehaus.aspectwerkz.hook.ClassLoaderPatcher; 21 import org.codehaus.aspectwerkz.hook.ClassLoaderPreProcessor; 22 import org.objectweb.asm.*; 23 24 30 public class AsmClassLoaderPreProcessor implements ClassLoaderPreProcessor { 31 private static final String DESC_CORE = "Ljava/lang/String;[BIILjava/security/ProtectionDomain;"; 32 private static final String DESC_PREFIX = "(" + DESC_CORE; 33 private static final String DESC_HELPER = "(Ljava/lang/ClassLoader;" + DESC_CORE + ")[B"; 34 35 public AsmClassLoaderPreProcessor() { 36 } 37 38 public byte[] preProcess(byte[] b) { 39 try { 40 ClassWriter w = new ClassWriter(true) { 41 private boolean flag; 42 public void visit(int version, int access, String name, String superName, String [] interfaces, String sourceFile) { 43 super.visit(version, access, name, superName, interfaces, sourceFile); 44 flag = name.equals("java/lang/ClassLoader"); } 46 public CodeVisitor visitMethod(int access, String name, String desc, String [] exceptions, Attribute attrs) { 47 CodeVisitor v = super.visitMethod(access, name, desc, exceptions, attrs); 48 if (flag) { 49 v = new PreProcessingVisitor(v, access, desc); 50 } 51 return v; 52 } 53 }; 54 new ClassReader(b).accept(w, false); 55 return w.toByteArray(); 56 } catch (Exception e) { 57 System.err.println("failed to patch ClassLoader:"); 58 e.printStackTrace(); 59 return b; 60 } 61 } 62 63 private static class PreProcessingVisitor extends RemappingCodeVisitor { 64 public PreProcessingVisitor(CodeVisitor v, int access, String desc) { 65 super(v, access, Type.getArgumentTypes(desc)); 66 } 67 68 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 69 if ("defineClass0".equals(name) && "java/lang/ClassLoader".equals(owner)) { 70 Type[] args = Type.getArgumentTypes(desc); 71 if (args.length < 5 || !desc.startsWith(DESC_PREFIX)) { 72 throw new Error ("non standard JDK, native call not supported: " + desc); 73 } 74 int[] locals = new int[args.length]; 75 for (int i = args.length - 1; i >= 0; i--) { 76 cv.visitVarInsn(args[i].getOpcode(Constants.ISTORE), 77 locals[i] = nextLocal(args[i].getSize())); 78 } 79 for (int i = 0; i < 5; i++) { 80 cv.visitVarInsn(args[i].getOpcode(Constants.ILOAD), locals[i]); 81 } 82 super.visitMethodInsn(Constants.INVOKESTATIC, 83 "org/codehaus/aspectwerkz/hook/impl/ClassPreProcessorHelper", 84 "defineClass0Pre", 85 DESC_HELPER); 86 cv.visitVarInsn(Constants.ASTORE, locals[1]); 87 cv.visitVarInsn(Constants.ALOAD, 0); 88 cv.visitVarInsn(Constants.ALOAD, locals[0]); cv.visitVarInsn(Constants.ALOAD, locals[1]); cv.visitInsn(Constants.ICONST_0); cv.visitVarInsn(Constants.ALOAD, locals[1]); 92 cv.visitInsn(Constants.ARRAYLENGTH); cv.visitVarInsn(Constants.ALOAD, locals[4]); for (int i = 5; i < args.length; i++) { 95 cv.visitVarInsn(args[i].getOpcode(Constants.ILOAD), locals[i]); 96 } 97 } 98 super.visitMethodInsn(opcode, owner, name, desc); 99 } 100 } 101 102 public static void main(String args[]) throws Exception { 103 ClassLoaderPreProcessor me = new AsmClassLoaderPreProcessor(); 104 InputStream is = ClassLoader.getSystemClassLoader().getParent().getResourceAsStream("java/lang/ClassLoader.class"); 105 byte[] out = me.preProcess(ClassLoaderPatcher.inputStreamToByteArray(is)); 106 is.close(); 107 OutputStream os = new FileOutputStream("_boot/java/lang/ClassLoader.class"); 108 os.write(out); 109 os.close(); 110 } 111 } 112 | Popular Tags |