@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); }
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(); } }
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; }
/** * 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); }
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 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 Class<? extends T> generate() { visitor.visitEnd(); byte[] bytecode = visitor.toByteArray(); return DEFINE_CLASS_METHOD.invoke( type.getClassLoader(), typeName, bytecode, 0, bytecode.length); }
/** * 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); } }
@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); } } }
private void build_boilerplate(ClassWriter cw) { String classname = "SVDBPersistenceDelegate"; String full_classname = transform_cls(fTargetPkg) + "/" + classname; cw.visit( Opcodes.V1_5, ACC_PROTECTED + ACC_PUBLIC + ACC_SUPER, full_classname, null, fBaseClass, null); cw.visitSource(classname + ".java", null); MethodVisitor mv; // Constructor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, fBaseClass, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); buildItemDispatchMethods(cw); buildObjectDispatchMethods(cw); }
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 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; }
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 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 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())); }
public byte[] genEABytecode() throws Exception { byte[] bytecodes = null; if (createBody) { eaCW.visitEnd(); bytecodes = eaCW.toByteArray(); } return bytecodes; }
@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(); }
public void startScript(StaticScope scope) { classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); // Create the class with the appropriate class name and source file classWriter.visit( javaVersion == null ? RubyInstanceConfig.JAVA_VERSION : javaVersion, ACC_PUBLIC + ACC_SUPER, getClassname(), null, p(AbstractScript.class), null); // add setPosition impl, which stores filename as constant to speed updates SkinnyMethodAdapter method = new SkinnyMethodAdapter( getClassVisitor(), ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "setPosition", sig(Void.TYPE, params(ThreadContext.class, int.class)), null, null); method.start(); method.aload(0); // thread context method.ldc(sourcename); method.iload(1); // line number method.invokevirtual( p(ThreadContext.class), "setFileAndLine", sig(void.class, String.class, int.class)); method.voidreturn(); method.end(); topLevelScope = scope; beginInit(); cacheCompiler = OptoFactory.newCacheCompiler(this); // This code was originally used to provide debugging info using JSR-45 // "SMAP" format. However, it breaks using normal Java traces to // generate Ruby traces, since the original path is lost. Reverting // to full path for now. // String sourceNoPath; // if (sourcename.indexOf("/") >= 0) { // String[] pathElements = sourcename.split("/"); // sourceNoPath = pathElements[pathElements.length - 1]; // } else if (sourcename.indexOf("\\") >= 0) { // String[] pathElements = sourcename.split("\\\\"); // sourceNoPath = pathElements[pathElements.length - 1]; // } else { // sourceNoPath = sourcename; // } final File sourceFile = new File(getSourcename()); // Revert to using original sourcename here, so that jitted traces match // interpreted traces. classWriter.visitSource(sourcename, sourceFile.getAbsolutePath()); }
@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(); }
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); }
@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(); }
@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); }
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 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(); }
public static Class<?> malform(Class<?> type) throws Exception { ClassReader classReader = new ClassReader(type.getName()); ClassWriter classWriter = new ClassWriter(classReader, 0); classReader.accept(new SignatureMalformer(classWriter), 0); ClassLoader classLoader = new ByteArrayClassLoader( null, Collections.singletonMap(type.getName(), classWriter.toByteArray()), null, ByteArrayClassLoader.PersistenceHandler.MANIFEST, PackageDefinitionStrategy.NoOp.INSTANCE); return classLoader.loadClass(type.getName()); }
protected static ClassWriter createClassWriter(String internalName, AccessorType accessorType) { ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); classWriter.visit( V1_6, ACC_PUBLIC + ACC_SUPER, internalName, null, "java/lang/Object", new String[] {getInternalName(accessorType.getAccessorType().getName())}); classWriter.visitSource(getExternalName(internalName), null); return classWriter; }
@Override public Object visitVarDec(VarDec varDec, Object arg) throws Exception { // System.out.println(varDec.type.getJVMType()); if (varDec.type.getJVMType().startsWith("Ljava/util/List")) fv = cw.visitField(ACC_STATIC, varDec.identToken.getText(), emptyList, null, null); else fv = cw.visitField( ACC_STATIC, varDec.identToken.getText(), varDec.type.getJVMType(), null, null); fv.visitEnd(); return null; // throw new UnsupportedOperationException("code generation not yet implemented"); }
private void buildObjectAccessor(ClassWriter cw, Class cls) { MethodVisitor mv; if (fDebugEn) { debug("--> buildAccessor cls=" + cls.getName()); } // Constructor String tgt_clsname = getClassName(cls); String cls_name = getClassLeafName(cls); // Read method // // 0 - this // 1 - parent // 2 - object mv = cw.visitMethod( ACC_PRIVATE, "read" + cls_name, "(L" + fChildItem + ";" + "L" + tgt_clsname + ";)V", null, new String[] {fDBFormatException}); mv.visitCode(); visit(false, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); // Write method // // 0 - this // 1 - object mv = cw.visitMethod( ACC_PRIVATE, "write" + cls_name, // "(L" + tgt_clsname + ";)V", "(L" + tgt_clsname + ";)V", null, new String[] {fDBWriteException}); mv.visitCode(); visit(true, tgt_clsname, mv, cls); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); if (fDebugEn) { debug("<-- buildAccessor cls=" + cls.getName()); } }
protected byte[] transformClass(byte[] bytes, String clssname) { InputStream is = getClass().getResourceAsStream("/" + clssname.replace('.', '/') + ".class"); ClassReader orig = null; try { ClassReader crRepl = new ClassReader(is); ClassNode cnRepl = new ClassNode(Opcodes.ASM4); crRepl.accept(cnRepl, ClassReader.SKIP_FRAMES); ClassReader crOrig = new ClassReader(bytes); ClassNode cnOrig = new ClassNode(Opcodes.ASM4); crOrig.accept(cnOrig, ClassReader.SKIP_FRAMES); for (Object ofnRepl : cnRepl.fields) { FieldNode fnRepl = (FieldNode) ofnRepl; if (hasReplaceAnnotation(fnRepl.visibleAnnotations)) { FieldNode fnOrig = findField(cnOrig.fields, fnRepl); if (fnOrig != null) { cnOrig.fields.remove(fnOrig); cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl)); } } else if (hasAddAnnotation(fnRepl.visibleAnnotations)) { cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl)); } } for (Object omnRepl : cnRepl.methods) { MethodNode mnRepl = (MethodNode) omnRepl; if (hasReplaceAnnotation(mnRepl.visibleAnnotations)) { MethodNode mnOrig = findMethod(cnOrig.methods, mnRepl); if (mnOrig != null) { cnOrig.methods.remove(mnOrig); cnOrig.methods.add(cnOrig.methods.size(), scrubMethod(cnOrig, cnRepl, mnRepl)); } } else if (hasAddAnnotation(mnRepl.visibleAnnotations)) { cnOrig.methods.add(cnOrig.methods.size() + 1, scrubMethod(cnOrig, cnRepl, mnRepl)); } } ClassWriter cwNew = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); cnOrig.accept(cwNew); return cwNew.toByteArray(); } catch (IOException e) { e.printStackTrace(); // To change body of catch statement use File | Settings | File // Templates. } return bytes; }