private String execute(final String name, final String code, final String input) throws Throwable { bc.compile(new StringReader(code), name, name, cw); ByteArrayOutputStream bos = new ByteArrayOutputStream(); InputStream is = System.in; PrintStream os = System.out; System.setIn(new ByteArrayInputStream(input.getBytes())); System.setOut(new PrintStream(bos)); try { TestClassLoader cl = new TestClassLoader(getClass().getClassLoader(), name, cw.toByteArray()); Class<?> c = cl.loadClass(name); Method m = c.getDeclaredMethod("main", new Class<?>[] {String[].class}); m.invoke(null, new Object[] {new String[0]}); } catch (InvocationTargetException ex) { throw ex.getCause(); } finally { System.setIn(is); System.setOut(os); } String output = new String(bos.toByteArray(), "ASCII"); System.out.println(code + " WITH INPUT '" + input + "' GIVES " + output); return output; }
public void toAsm(JarOutputStream jos) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); // ClassWriter cw = new ClassWriter(0); CheckClassAdapter cca = new CheckClassAdapter(cw); cca.visit(version, access, name, sig, superName, interfaces); Iterator it = fieldVisitors.entrySet().iterator(); while (it.hasNext()) { Map.Entry pairs = (Map.Entry) it.next(); ByteCodeFieldVisitor fv = (ByteCodeFieldVisitor) pairs.getValue(); fv.toAsm(cca); } it = methodVisitors.entrySet().iterator(); while (it.hasNext()) { Map.Entry pairs = (Map.Entry) it.next(); ByteCodeMethodVisitor mv = (ByteCodeMethodVisitor) pairs.getValue(); mv.toAsm(cca); } byte[] bytes = cw.toByteArray(); if (ProjectProperties.getBoolean("fortress.bytecode.verify", false)) { PrintWriter pw = new PrintWriter(System.out); CheckClassAdapter.verify(new ClassReader(bytes), true, pw); } System.out.println("About to write " + name); ByteCodeWriter.writeJarredClass(jos, name, bytes); }
public static byte[] getBytesFromClassNode(ClassNode c) { ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); c.accept(w); byte[] b = w.toByteArray(); SquidAPIPlugin.LOGGER.info("Successfully transformed " + c.name.replace("/", "."), "."); return b; }
@SuppressWarnings("unused") @Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { return super.findClass(name); } catch (ClassNotFoundException e) { byte[] def = mClassDefs.get(name); if (def != null) { // Load the modified ClassWithNative from its bytes representation. return defineClass(name, def, 0, def.length); } try { // Load everything else from the original definition into the new class loader. ClassReader cr = new ClassReader(name); ClassWriter cw = new ClassWriter(0); cr.accept(cw, 0); byte[] bytes = cw.toByteArray(); return defineClass(name, bytes, 0, bytes.length); } catch (IOException ioe) { throw new RuntimeException(ioe); } } }
/** * Generates interface class using collection of rules. * * @param className name of result class * @param rules collection of rules what will be used as interface methods * @param classLoader class loader what will be used to load generated interface * @return generated interface * @throws Exception if an error has occurred */ public static Class<?> generateInterface( String className, RuleInfo[] rules, ClassLoader classLoader) throws Exception { ClassWriter classWriter = new ClassWriter(0); String name = className.replace('.', '/'); classWriter.visit(Opcodes.V1_5, PUBLIC_ABSTRACT_INTERFACE, name, null, JAVA_LANG_OBJECT, null); for (RuleInfo ruleInfo : rules) { String ruleName = ruleInfo.getName(); classWriter.visitMethod(PUBLIC_ABSTRACT, ruleName, getMethodTypes(ruleInfo), null, null); } classWriter.visitEnd(); // Create class object. // ReflectUtils.defineClass(className, classWriter.toByteArray(), classLoader); // Return loaded to classpath class object. // return Class.forName(className, true, classLoader); }
/** * Chain together a ClassReader than will read the given class and a ClassWriter to write out a * new class with an adapter in the middle to add annotations * * @param fromName the name of the class we're coming from */ private static void adaptClass(String fromName) { if (VERBOSE) System.out.println("Adding annotations to class: " + fromName); // gets an input stream to read the bytecode of the class String resource = fromName.replace('.', '/') + ".class"; InputStream is = BootstrapClassLoader.getBootstrapClassLoader().getResourceAsStream(resource); byte[] b; // adapts the class on the fly try { ClassReader cr = new ClassReader(is); ClassWriter cw = new ClassWriter(0); ClassVisitor cv = new AddAnnotationClassAdapter(cw, fromName); cr.accept(cv, 0); b = cw.toByteArray(); } catch (Exception e) { throw new Error("Couldn't find class " + fromName + " (" + resource + ")", e); } // store the adapted class on disk try { File file = new File(destinationDir + resource); new File(file.getParent()).mkdirs(); // ensure we have a directory to write to FileOutputStream fos = new FileOutputStream(file); fos.write(b); fos.close(); } catch (Exception e) { throw new Error("Error writing to " + destinationDir + resource + " to disk", e); } }
public static byte[] dumpInner() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit(V1_4, ACC_SUPER, "pkg/Outer$Inner", null, "java/lang/Object", null); cw.visitInnerClass("pkg/Outer$Inner", "pkg/Outer", "C", 0); fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); fv.visitEnd(); mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, "pkg/Outer$Inner", "this$0", "Lpkg/Outer;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (transformedName.equals("net.minecraft.block.BlockDynamicLiquid") && CoreLoadingPlugin.util.getBoolean("FiniteWater", false)) { ClassReader reader = new ClassReader(bytes); ClassNode node = new ClassNode(); reader.accept(node, 0); InsnList getSmallestFlowDecay = new InsnList(); getSmallestFlowDecay.add(new VarInsnNode(ALOAD, 0)); getSmallestFlowDecay.add(new InsnNode(ICONST_0)); getSmallestFlowDecay.add( new FieldInsnNode( PUTFIELD, "net/minecraft/block/BlockDynamicLiquid", "field_149815_a", "I")); for (MethodNode method : node.methods) if ("func_149810_a" .equals( FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(name, method.name, method.desc))) method.instructions.insertBefore(method.instructions.getFirst(), getSmallestFlowDecay); ClassWriter writer = new ClassWriter(0); node.accept(writer); return writer.toByteArray(); } return bytes; }
public void test() throws Exception { ClassWriter cw = new ClassWriter(0); CheckClassAdapter ca = new CheckClassAdapter(cw); ClassVisitor cv = getClassAdapter(ca); generateBasicClass(cv); checkClass(defineClass("C", cw.toByteArray())); }
public Class<? extends T> generate() { visitor.visitEnd(); byte[] bytecode = visitor.toByteArray(); return DEFINE_CLASS_METHOD.invoke( type.getClassLoader(), typeName, bytecode, 0, bytecode.length); }
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException { try { ClassReader classReader = new ClassReader("com/asm/Before_Demo1"); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassAdapter ca = new AopClassAdapter(cw); classReader.accept(ca, ClassReader.SKIP_DEBUG); byte[] byteArray = cw.toByteArray(); MyClassLoader myClassLoader = new MyClassLoader(); Class<?> clazz = myClassLoader.myDefineClass(byteArray, "com.asm.Before_Demo1"); Method method = clazz.getMethod("sayHello"); method.invoke(clazz.newInstance()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
private static void transformIfNeccessary(File file) throws IOException { InputStream is = new FileInputStream(file); ClassNode cn; try { ClassReader cr = new ClassReader(is); cn = new ClassNode(); cr.accept(cn, 0); } finally { is.close(); } if (!isAlreadyTransformed(cn) && isAnnotationPresent(cn)) { System.out.println("Transforming file " + file); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassVisitor ca = new CheckClassAdapter(cw); ClassVisitor cv = new PropertyChangeSupportAdapter(ca); cn.accept(cv); FileOutputStream os = new FileOutputStream(file); try { os.write(cw.toByteArray()); } finally { os.close(); } } }
private static byte[] visitEnd() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, RubyIDClassName, null, "java/lang/Object", null); Method staticBlock = Method.getMethod("void <clinit> ()V"); GeneratorAdapter staticBlockMg = new GeneratorAdapter(Opcodes.ACC_STATIC, staticBlock, null, null, cw); for (Map.Entry<String, String> e : idMap.entrySet()) { cw.visitField( Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, e.getValue(), Types.RUBY_ID_TYPE.getDescriptor(), null, null); staticBlockMg.push(e.getKey()); staticBlockMg.invokeStatic( Type.getType(RubyID.class), Method.getMethod("com.xruby.runtime.lang.RubyID intern(String)")); staticBlockMg.putStatic( Type.getType("L" + RubyIDClassName + ";"), e.getValue(), Types.RUBY_ID_TYPE); } staticBlockMg.returnValue(); staticBlockMg.endMethod(); cw.visitEnd(); return cw.toByteArray(); }
@Override public void parse( final BytecodeArtifact bytecodeArtifact, final IPathResolver directoryResolver) { assert null != bytecodeArtifact : "Parameter 'bytecodeArtifact' of method 'parse' must not be null"; /** (1) */ final ClassReader cr = new ClassReader(bytecodeArtifact.getBytesOriginal()); /** (2) */ // cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); final ClassWriter cw = new ClassWriter(cr, 0); /** (3) */ final ASMClassInstrumentor ca = constructSelf(cw); /** (4) */ cr.accept(ca, ClassReader.EXPAND_FRAMES); assert null != ca : "'ca' of method 'parse' must not be null"; assert null != cw : "'cw' of method 'parse' must not be null"; final String fileAbsolutePath = bytecodeArtifact.absolutePath(); this.benchmark.addBytecodeArtificatAnalysed( ca.className, cw.toByteArray(), fileAbsolutePath, directoryResolver, bytecodeArtifact.isClassFile(), this.isInterface); }
private static Map<String, Class<?>> defineClasses( List<ClassDefinition> classDefinitions, DynamicClassLoader classLoader) { ClassInfoLoader classInfoLoader = ClassInfoLoader.createClassInfoLoader(classDefinitions, classLoader); if (DUMP_BYTE_CODE_TREE) { ByteArrayOutputStream out = new ByteArrayOutputStream(); DumpByteCodeVisitor dumpByteCode = new DumpByteCodeVisitor(new PrintStream(out)); for (ClassDefinition classDefinition : classDefinitions) { dumpByteCode.visitClass(classDefinition); } System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8)); } Map<String, byte[]> byteCodes = new LinkedHashMap<>(); for (ClassDefinition classDefinition : classDefinitions) { ClassWriter cw = new SmartClassWriter(classInfoLoader); classDefinition.visit(cw); byte[] byteCode = cw.toByteArray(); if (RUN_ASM_VERIFIER) { ClassReader reader = new ClassReader(byteCode); CheckClassAdapter.verify(reader, classLoader, true, new PrintWriter(System.out)); } byteCodes.put(classDefinition.getType().getJavaClassName(), byteCode); } String dumpClassPath = DUMP_CLASS_FILES_TO.get(); if (dumpClassPath != null) { for (Map.Entry<String, byte[]> entry : byteCodes.entrySet()) { File file = new File( dumpClassPath, ParameterizedType.typeFromJavaClassName(entry.getKey()).getClassName() + ".class"); try { log.debug("ClassFile: " + file.getAbsolutePath()); Files.createParentDirs(file); Files.write(entry.getValue(), file); } catch (IOException e) { log.error(e, "Failed to write generated class file to: %s" + file.getAbsolutePath()); } } } if (DUMP_BYTE_CODE_RAW) { for (byte[] byteCode : byteCodes.values()) { ClassReader classReader = new ClassReader(byteCode); classReader.accept( new TraceClassVisitor(new PrintWriter(System.err)), ClassReader.SKIP_FRAMES); } } Map<String, Class<?>> classes = classLoader.defineClasses(byteCodes); try { for (Class<?> clazz : classes.values()) { Reflection.initialize(clazz); } } catch (VerifyError e) { throw new RuntimeException(e); } return classes; }
public byte[] genEABytecode() throws Exception { byte[] bytecodes = null; if (createBody) { eaCW.visitEnd(); bytecodes = eaCW.toByteArray(); } return bytecodes; }
public void test() throws Exception { ClassWriter cw = new ClassWriter(0); CheckClassAdapter ca = new CheckClassAdapter(cw); RemoveAnnotationAdapter ra = new RemoveAnnotationAdapter(ca, "Ljava/lang/Deprecated;"); AddAnnotationAdapter aa = new AddAnnotationAdapter(ra, "Ljava/lang/Deprecated;"); generateBasicClass(aa); checkClass(defineClass("C", cw.toByteArray())); }
@Override public byte[] transform(String className, String transformedClassName, byte[] bytes) { String methodName; if (className.equals(OBF_CLASS)) { methodName = SRG_METHOD; } else if (className.equals(MCP_CLASS)) { methodName = MCP_METHOD; } else { return bytes; } ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0); for (MethodNode method : classNode.methods) { if (method.name.equals(methodName) && method.desc.equals(METHOD_DESC)) { logger.info("CraftingTweaks will now patch {} in {}...", methodName, className); MethodNode mn = new MethodNode(); Label notClicked = new Label(); // mn.visitMethodInsn(Opcodes.INVOKESTATIC, "org/lwjgl/input/Mouse", "getEventButtonState", // "()Z", false); // mn.visitJumpInsn(Opcodes.IFEQ, notClicked); // if getEventButtonState false, continue // after mn.visitVarInsn(Opcodes.ILOAD, 1); // push mouseX mn.visitVarInsn(Opcodes.ILOAD, 2); // push mouseY mn.visitVarInsn(Opcodes.ILOAD, 3); // push button mn.visitMethodInsn( Opcodes.INVOKESTATIC, "net/blay09/mods/craftingtweaks/CraftingTweaks", "onGuiClick", "(III)Z", false); // call onGuiClick mn.visitJumpInsn(Opcodes.IFEQ, notClicked); // if onGuiClick false, continue after mn.visitInsn(Opcodes.RETURN); // otherwise stop here mn.visitLabel(notClicked); // continue from here AbstractInsnNode insertAfter = null; for (int i = 0; i < method.instructions.size(); i++) { AbstractInsnNode node = method.instructions.get(i); if (node instanceof VarInsnNode) { if (node.getOpcode() == Opcodes.ISTORE && ((VarInsnNode) node).var == 3) { // ISTORE 3 insertAfter = node; break; } } } if (insertAfter != null) { method.instructions.insert(insertAfter, mn.instructions); logger.info("CraftingTweaks successfully patched {} in {}!", methodName, className); } else { logger.warn( "CraftingTweaks failed to patch {0}::{1} ({2} not found) - transfering into crafting grids will not work!", className, methodName, "ISTORE 3"); } } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }
static void optimize(final File f, final File d, final Remapper remapper) throws IOException { if (f.isDirectory()) { File[] files = f.listFiles(); for (int i = 0; i < files.length; ++i) { optimize(files[i], d, remapper); } } else if (f.getName().endsWith(".class")) { ConstantPool cp = new ConstantPool(); ClassReader cr = new ClassReader(new FileInputStream(f)); // auto-boxing removal requires to recompute the maxs ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassConstantsCollector ccc = new ClassConstantsCollector(cw, cp); ClassOptimizer co = new ClassOptimizer(ccc, remapper); cr.accept(co, ClassReader.SKIP_DEBUG); Set<Constant> constants = new TreeSet<Constant>(new ConstantComparator()); constants.addAll(cp.values()); cr = new ClassReader(cw.toByteArray()); cw = new ClassWriter(0); Iterator<Constant> i = constants.iterator(); while (i.hasNext()) { Constant c = i.next(); c.write(cw); } cr.accept(cw, ClassReader.SKIP_DEBUG); if (MAPPING.get(cr.getClassName() + "/remove") != null) { return; } String n = remapper.mapType(cr.getClassName()); File g = new File(d, n + ".class"); if (!g.exists() || g.lastModified() < f.lastModified()) { if (!g.getParentFile().exists() && !g.getParentFile().mkdirs()) { throw new IOException("Cannot create directory " + g.getParentFile()); } OutputStream os = new FileOutputStream(g); try { os.write(cw.toByteArray()); } finally { os.close(); } } } }
private void writeClass(String classname, File destination, ClassWriter writer) throws IOException { // verify the class byte[] bytecode = writer.toByteArray(); if (VERIFY_CLASSFILES) CheckClassAdapter.verify(new ClassReader(bytecode), false, new PrintWriter(System.err)); writeClassFile(destination, bytecode, classname); }
public static byte[] dump1() { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); FieldVisitor fv; MethodVisitor mv; cw.visit(V1_4, ACC_SUPER, "pkg/Outer$1", null, "pkg/Outer", null); cw.visitOuterClass("pkg/Outer", "m", "()V"); cw.visitInnerClass("pkg/Outer$1", null, null, 0); fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "Lpkg/Outer;", null, null); fv.visitEnd(); mv = cw.visitMethod(0, "<init>", "(Lpkg/Outer;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "pkg/Outer", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); mv = cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null); mv.visitCode(); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(" "); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "pkg/Outer$1", "this$0", "Lpkg/Outer;"); mv.visitMethodInsn(INVOKESTATIC, "pkg/Outer", "access$000", "(Lpkg/Outer;)I"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }
private static byte[] generate(String name, Class<?> type, Class<?> parameter) { name = name.replace('.', '/'); String typeName = Type.getInternalName(type); String typeDesc = Type.getDescriptor(type); String parameterName = Type.getInternalName(parameter); String parameterDesc = Type.getDescriptor(parameter); String constructSignature = '(' + parameterDesc + ')' + typeDesc; ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, BASE_CLASS, null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Class;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "<init>", "(Ljava/lang/Class;)V", false); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "construct", constructSignature, null, null); mv.visitCode(); mv.visitTypeInsn(NEW, typeName); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, typeName, "<init>", '(' + parameterDesc + ")V", false); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { mv = cw.visitMethod( ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "construct", "(Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, parameterName); mv.visitMethodInsn(INVOKEVIRTUAL, name, "construct", constructSignature, false); mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { if (!"net.minecraft.item.ItemStack".equals(name)) return basicClass; ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); FieldNode itemField = null; for (FieldNode f : classNode.fields) { if (ITEM_TYPE.equals(f.desc) && itemField == null) { itemField = f; } else if (ITEM_TYPE.equals(f.desc)) { throw new RuntimeException("Error processing ItemStack - found a duplicate Item field"); } } if (itemField == null) { throw new RuntimeException( "Error processing ItemStack - no Item field declared (is the code somehow obfuscated?)"); } MethodNode getItemMethod = null; for (MethodNode m : classNode.methods) { if (GETITEM_DESC.equals(m.desc) && getItemMethod == null) { getItemMethod = m; } else if (GETITEM_DESC.equals(m.desc)) { throw new RuntimeException("Error processing ItemStack - duplicate getItem method found"); } } if (getItemMethod == null) { throw new RuntimeException( "Error processing ItemStack - no getItem method found (is the code somehow obfuscated?)"); } for (MethodNode m : classNode.methods) { for (ListIterator<AbstractInsnNode> it = m.instructions.iterator(); it.hasNext(); ) { AbstractInsnNode insnNode = it.next(); if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) { FieldInsnNode fi = (FieldInsnNode) insnNode; if (itemField.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) { it.remove(); MethodInsnNode replace = new MethodInsnNode( Opcodes.INVOKEVIRTUAL, "net/minecraft/item/ItemStack", getItemMethod.name, getItemMethod.desc, false); it.add(replace); } } } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }
public void dumpClass(PrintStream out) { PrintWriter pw = new PrintWriter(out); try { TraceClassVisitor tcv = new TraceClassVisitor(pw); new ClassReader(classWriter.toByteArray()).accept(tcv, 0); } finally { pw.close(); } }
private void build() { ClassWriter cw = new ClassWriter(0); final ClassLoader cl = getClass().getClassLoader(); for (SVDBItemType t : SVDBItemType.values()) { Class cls = null; for (String pkg : fTargetPkgList) { try { cls = cl.loadClass(pkg + ".SVDB" + t.name()); } catch (Exception e) { } if (cls != null) { break; } } if (cls != null) { // Found a class to process fTypeClassMap.put(t, cls); } else { System.out.println("Error: Failed to find item " + t.name()); } } // long start = System.currentTimeMillis(); build_boilerplate(cw); for (SVDBItemType t : fTypeClassMap.keySet()) { Class cls = fTypeClassMap.get(t); buildItemAccessor(cw, t, cls); } for (Class c : fClassList) { buildObjectAccessor(cw, c); } cw.visitEnd(); JITClassLoader jit_cl = new JITClassLoader(cl, cw.toByteArray()); try { fDelegateCls = (Class<JITPersistenceDelegateBase>) jit_cl.loadClass(fTargetPkg + ".SVDBPersistenceDelegate"); } catch (Exception e) { e.printStackTrace(); } /* long end = System.currentTimeMillis(); System.out.println("Class-build time: " + (end-start)); System.out.println("Size: " + cw.toByteArray().length); */ }
protected Class findClass(String name) { ClassWriter writer = new ClassWriter(true); writer.visit( Constants.ACC_PUBLIC | Constants.ACC_INTERFACE, name.replace('.', '/'), "java/lang/Object", null, null); byte[] b = writer.toByteArray(); return defineClass(name, b, 0, b.length); }
public Class<?> createWrapper(Method callback) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); String eventType = Type.getInternalName(callback.getParameterTypes()[0]); /* System.out.println("Name: " + name); System.out.println("Desc: " + desc); System.out.println("InstType: " + instType); System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback)); System.out.println("Event: " + eventType); */ cw.visit( V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[] {HANDLER_DESC}); cw.visitSource(".dynamic", null); { cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, instType); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, eventType); mv.visitMethodInsn( INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback)); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return LOADER.define(name, cw.toByteArray()); }
@Override public void compile(boolean result, IEnvironmentMethod environment) { if (!result) return; Method method = interfaceClass.getMethods()[0]; // generate class String clsName = environment.makeClassName(); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit( Opcodes.V1_6, Opcodes.ACC_PUBLIC, clsName, null, "java/lang/Object", new String[] {internal(interfaceClass)}); MethodOutput constructor = new MethodOutput(cw, Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); constructor.start(); constructor.loadObject(0); constructor.invokeSpecial("java/lang/Object", "<init>", "()V"); constructor.ret(); constructor.end(); MethodOutput output = new MethodOutput(cw, Opcodes.ACC_PUBLIC, method.getName(), descriptor(method), null, null); IEnvironmentClass environmentClass = new EnvironmentClass(cw, environment); IEnvironmentMethod environmentMethod = new EnvironmentMethod(output, environmentClass); for (int i = 0; i < arguments.size(); i++) { environmentMethod.putValue( arguments.get(i).getName(), new SymbolArgument(i + 1, environment.getType(method.getGenericParameterTypes()[i])), getPosition()); } output.start(); for (Statement statement : statements) { statement.compile(environmentMethod); } output.ret(); output.end(); environment.putClass(clsName, cw.toByteArray()); // make class instance environment.getOutput().newObject(clsName); environment.getOutput().dup(); environment.getOutput().construct(clsName); }
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { if (basicClass == null) return null; ClassReader reader = new ClassReader(basicClass); ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassVisitor visitor = writer; visitor = new ExitVisitor(visitor); reader.accept(visitor, 0); return writer.toByteArray(); }
private byte[] transformEntitySheep(byte[] bytes) { System.out.println("Transforming EntitySheep..."); ClassNode cn = new ClassNode(); ClassReader cr = new ClassReader(bytes); cr.accept(cn, 0); Iterator<MethodNode> methods = cn.methods.iterator(); while (methods.hasNext()) { MethodNode m = methods.next(); if (m.name.equals(names.get("entitySheep_setColour_func")) && m.desc.equals(names.get("entitySheep_setColour_desc"))) { System.out.println("Found target method: " + m.name + m.desc + "! Inserting call..."); for (int idx = 0; idx < m.instructions.size(); idx++) { if (m.instructions.get(idx).getOpcode() == Opcodes.ISTORE) { System.out.println("Found ISTORE at index " + idx + ", inserting code afterwards..."); idx++; // AFTERwards, not before ;) InsnList toAdd = new InsnList(); // to mark the end of the code LabelNode lmmnode = new LabelNode(new Label()); // load this toAdd.add(new VarInsnNode(Opcodes.ALOAD, 0)); // new fleece colour toAdd.add(new VarInsnNode(Opcodes.ILOAD, 1)); // old fleece colour toAdd.add(new VarInsnNode(Opcodes.ILOAD, 2)); toAdd.add( new MethodInsnNode( Opcodes.INVOKESTATIC, "keepcalm/mods/events/ForgeEventHelper", "onSheepDye", "(L" + names.get("entitySheep_javaName") + ";II)Z")); LabelNode endIf = new LabelNode(new Label()); toAdd.add(new JumpInsnNode(Opcodes.IFEQ, endIf)); toAdd.add(new InsnNode(Opcodes.RETURN)); toAdd.add(endIf); toAdd.add(lmmnode); m.instructions.insertBefore(m.instructions.get(idx), toAdd); break; } } } } ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cn.accept(cw); return cw.toByteArray(); }