List of usage examples for org.objectweb.asm.tree ClassNode accept
public void accept(final ClassVisitor classVisitor)
From source file:net.dv8tion.ClassTransformer.java
License:Apache License
/** * Helper method to modify the getAllUsernames method in ServerConfigurationManager. * Takes into account obfuscated method names based on boolean. * /*from w ww.j a v a2s .c o m*/ * Replaces the call "return astring" at the end of ServerConfigurationManager's * getAllUsernames method with "return NameLoader.loadNames(astring)" * Because of how The JVM and ByteCode work with arrays, we do not need to * remove any instructions, only inject code. The array "astring" in the * call "return astring" will be provided as the param for the loadNames method. * * @param className * The class name, proceeded by the package it is in, if it is in one. * @param classData * The byte code of the class. * @param obfuscated * Is the code obfuscated? * @return * Returns the modified byte code of the class. */ public byte[] patchClassWithASM(String className, byte[] classData, boolean obfuscated) { String methodName = obfuscated ? "d" : "getAllUsernames"; ClassNode classNode = new ClassNode(Opcodes.ASM4); ClassReader classReader = new ClassReader(classData); classReader.accept(classNode, ClassReader.EXPAND_FRAMES); Iterator<MethodNode> methods = classNode.methods.iterator(); while (methods.hasNext()) { MethodNode m = methods.next(); int arrayReturn_index = -1; if ((m.name.equals(methodName) && m.desc.equals("()[Ljava/lang/String;"))) { AbstractInsnNode currentNode = null; Iterator<AbstractInsnNode> iter = m.instructions.iterator(); int index = -1; while (iter.hasNext()) { index++; currentNode = iter.next(); if (currentNode.getOpcode() == Opcodes.ARETURN) { arrayReturn_index = index; } } //Calls NameLoader.loadNames(String[]) m.instructions.insertBefore(m.instructions.get(arrayReturn_index), new MethodInsnNode(Opcodes.INVOKESTATIC, "net/dv8tion/NameLoader", "loadNames", "([Ljava/lang/String;)[Ljava/lang/String;")); System.out.println("[IRC NameBridge] Patching Complete!"); break; } } //ASM specific for cleaning up and returning the final bytes for JVM processing. //Use 0 here instead of like ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS because //We need to have ASM recalculate things. ClassWriter writer = new ClassWriter(0); classNode.accept(writer); return writer.toByteArray(); }
From source file:net.epoxide.surge.asm.ASMUtils.java
License:Creative Commons License
/** * Converts a ClassNode into a byte array which can then be returned by your transformer. * * @param classNode: An instance of the ClassNode you wish to convert into a byte array. * @param flags: The flags to use when converting the ClassNode. These are generally * COMPUTE_FRAMES and COMPUTE_MAXS. * @return byte[]: A byte array representation of the ClassNode. *///from w w w .j a v a 2 s. c o m public static byte[] createByteArrayFromClass(ClassNode classNode, int flags) { final ClassWriter classWriter = new ClassWriter(flags); classNode.accept(classWriter); return classWriter.toByteArray(); }
From source file:net.fabricmc.base.transformer.AccessTransformer.java
License:Apache License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (!name.startsWith("net.minecraft")) { return bytes; }//from w w w. ja v a 2s. c o m ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0); boolean isClassProtected = classNode.access == Opcodes.ACC_PROTECTED; boolean isClassPrivate = classNode.access == Opcodes.ACC_PRIVATE; if (isClassProtected || isClassPrivate) { classNode.access = Opcodes.ACC_PUBLIC; } for (MethodNode method : classNode.methods) { boolean isProtected = method.access == Opcodes.ACC_PROTECTED; boolean isPrivate = method.access == Opcodes.ACC_PRIVATE; if (isProtected || isPrivate) { method.access = Opcodes.ACC_PUBLIC; } } for (FieldNode field : classNode.fields) { boolean isProtected = field.access == Opcodes.ACC_PROTECTED; boolean isPrivate = field.access == Opcodes.ACC_PRIVATE; if (isProtected || isPrivate) { field.access = Opcodes.ACC_PUBLIC; } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }
From source file:net.fabricmc.weave.merge.ClassMerger.java
License:Apache License
public byte[] merge(byte[] classClient, byte[] classServer) { ClassReader readerC = new ClassReader(classClient); ClassReader readerS = new ClassReader(classServer); ClassWriter writer = new ClassWriter(0); ClassNode nodeC = new ClassNode(Opcodes.ASM5); readerC.accept(nodeC, 0);/* w w w.j av a2 s . c o m*/ ClassNode nodeS = new ClassNode(Opcodes.ASM5); readerS.accept(nodeS, 0); ClassNode nodeOut = new ClassNode(Opcodes.ASM5); nodeOut.version = nodeC.version; nodeOut.access = nodeC.access; nodeOut.name = nodeC.name; nodeOut.signature = nodeC.signature; nodeOut.interfaces = nodeC.interfaces; nodeOut.superName = nodeC.superName; nodeOut.sourceFile = nodeC.sourceFile; nodeOut.sourceDebug = nodeC.sourceDebug; nodeOut.outerClass = nodeC.outerClass; nodeOut.outerMethod = nodeC.outerMethod; nodeOut.outerMethodDesc = nodeC.outerMethodDesc; nodeOut.invisibleAnnotations = nodeC.invisibleAnnotations; nodeOut.invisibleTypeAnnotations = nodeC.invisibleTypeAnnotations; nodeOut.visibleAnnotations = nodeC.visibleAnnotations; nodeOut.visibleTypeAnnotations = nodeC.visibleTypeAnnotations; nodeOut.attrs = nodeC.attrs; new Merger<InnerClassNode>(nodeC.innerClasses, nodeS.innerClasses) { @Override public String getName(InnerClassNode entry) { return entry.name; } @Override public void applySide(InnerClassNode entry, String side) { } }.merge(nodeOut.innerClasses); new Merger<FieldNode>(nodeC.fields, nodeS.fields) { @Override public String getName(FieldNode entry) { return entry.name + "," + entry.desc + "," + entry.signature; } @Override public void applySide(FieldNode entry, String side) { AnnotationVisitor av = entry.visitAnnotation("Lnet/fabricmc/api/Sided;", true); visitSideAnnotation(av, side); } }.merge(nodeOut.fields); new Merger<MethodNode>(nodeC.methods, nodeS.methods) { @Override public String getName(MethodNode entry) { return entry.name + "," + entry.desc + "," + entry.signature; } @Override public void applySide(MethodNode entry, String side) { AnnotationVisitor av = entry.visitAnnotation("Lnet/fabricmc/api/Sided;", true); visitSideAnnotation(av, side); } }.merge(nodeOut.methods); nodeOut.accept(writer); return writer.toByteArray(); }
From source file:net.lyonlancer5.mcmp.karasu.asm.KarasuTransformer.java
License:Apache License
private static byte[] transform(int index, byte[] classBeingTransformed) { try {/*from ww w.j av a 2 s. c o m*/ ClassNode e = new ClassNode(); ClassReader classReader = new ClassReader(classBeingTransformed); classReader.accept(e, 0); switch (index) { case 0: transformEntityLivingBase(e); default: ClassWriter classWriter = new ClassWriter(1); e.accept(classWriter); return classWriter.toByteArray(); } } catch (Exception var6) { var6.printStackTrace(); return classBeingTransformed; } }
From source file:net.malisis.core.asm.MalisisClassTransformer.java
License:Open Source License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { ArrayList<AsmHook> hooks = listHooks.get(transformedName); if (hooks == null || hooks.size() == 0) return bytes; LogManager.getLogger(logString).info("Found hooks for {} ({})", transformedName, name); ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0);// w w w. j ava 2 s.c o m for (AsmHook hook : hooks) { MethodNode methodNode = AsmUtils.findMethod(classNode, hook.getMethodName(), hook.getMethodDescriptor()); if (methodNode != null) { if (!hook.walkSteps(methodNode)) LogManager.getLogger(logString).error("The instruction list was not found in {}:{}{}", hook.getTargetClass(), hook.getMethodName(), hook.getMethodDescriptor()); if (hook.isDebug() == true && !MalisisCore.isObfEnv) { System.err.println(AsmUtils.getMethodNodeAsString(methodNode)); } } else { LogManager.getLogger(logString).error("Method not found : {}:{}{}", hook.getTargetClass(), hook.getMethodName(), hook.getMethodDescriptor()); } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS /* | ClassWriter.COMPUTE_FRAMES */); classNode.accept(writer); return writer.toByteArray(); }
From source file:net.minecraftforge.fml.common.asm.transformers.AccessTransformer.java
License:Open Source License
@Override public byte[] transform(String name, String transformedName, byte[] bytes) { if (bytes == null) { return null; }//from ww w .j a v a 2s.com if (DEBUG) { FMLRelaunchLog.fine("Considering all methods and fields on %s (%s)\n", transformedName, name); } if (!modifiers.containsKey(transformedName)) { return bytes; } ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(bytes); classReader.accept(classNode, 0); Collection<Modifier> mods = modifiers.get(transformedName); for (Modifier m : mods) { if (m.modifyClassVisibility) { classNode.access = getFixedAccess(classNode.access, m); if (DEBUG) { System.out.println(String.format("Class: %s %s -> %s", name, toBinary(m.oldAccess), toBinary(m.newAccess))); } continue; } if (m.desc.isEmpty()) { for (FieldNode n : classNode.fields) { if (n.name.equals(m.name) || m.name.equals("*")) { n.access = getFixedAccess(n.access, m); if (DEBUG) { System.out.println(String.format("Field: %s.%s %s -> %s", name, n.name, toBinary(m.oldAccess), toBinary(m.newAccess))); } if (!m.name.equals("*")) { break; } } } } else { List<MethodNode> nowOverridable = Lists.newArrayList(); for (MethodNode n : classNode.methods) { if ((n.name.equals(m.name) && n.desc.equals(m.desc)) || m.name.equals("*")) { n.access = getFixedAccess(n.access, m); // constructors always use INVOKESPECIAL if (!n.name.equals("<init>")) { // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL // so that overridden methods will be called. Only need to scan this class, because obviously the method was private. boolean wasPrivate = (m.oldAccess & ACC_PRIVATE) == ACC_PRIVATE; boolean isNowPrivate = (m.newAccess & ACC_PRIVATE) == ACC_PRIVATE; if (wasPrivate && !isNowPrivate) { nowOverridable.add(n); } } if (DEBUG) { System.out.println(String.format("Method: %s.%s%s %s -> %s", name, n.name, n.desc, toBinary(m.oldAccess), toBinary(m.newAccess))); } if (!m.name.equals("*")) { break; } } } replaceInvokeSpecial(classNode, nowOverridable); } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }
From source file:net.minecraftforge.fml.common.asm.transformers.FieldRedirectTransformer.java
License:Open Source License
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { if (!this.clsName.equals(transformedName)) return basicClass; ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0);/*w w w .j av a 2s . co m*/ FieldNode fieldRef = null; for (FieldNode f : classNode.fields) { if (this.TYPE.equals(f.desc) && fieldRef == null) { fieldRef = f; } else if (this.TYPE.equals(f.desc)) { throw new RuntimeException("Error processing " + clsName + " - found a duplicate holder field"); } } if (fieldRef == null) { throw new RuntimeException("Error processing " + clsName + " - no holder field declared (is the code somehow obfuscated?)"); } MethodNode getMethod = null; for (MethodNode m : classNode.methods) { if (m.name.equals(this.bypass)) continue; if (this.DESC.equals(m.desc) && getMethod == null) { getMethod = m; } else if (this.DESC.equals(m.desc)) { throw new RuntimeException("Error processing " + clsName + " - duplicate get method found"); } } if (getMethod == null) { throw new RuntimeException( "Error processing " + clsName + " - no get method found (is the code somehow obfuscated?)"); } for (MethodNode m : classNode.methods) { if (m.name.equals(this.bypass)) continue; for (ListIterator<AbstractInsnNode> it = m.instructions.iterator(); it.hasNext();) { AbstractInsnNode insnNode = it.next(); if (insnNode.getType() == AbstractInsnNode.FIELD_INSN) { FieldInsnNode fi = (FieldInsnNode) insnNode; if (fieldRef.name.equals(fi.name) && fi.getOpcode() == Opcodes.GETFIELD) { it.remove(); MethodInsnNode replace = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classNode.name, getMethod.name, getMethod.desc, false); it.add(replace); } } } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); }
From source file:net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer.java
License:Open Source License
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { if (transformedName.equals("paulscode.sound.Source")) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "removed", "Z", null, null)); // adding field 'public boolean removed;' ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } else if (transformedName.equals("paulscode.sound.Library")) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); MethodNode method = null;/*from w w w . j a v a 2s. c o m*/ for (MethodNode m : classNode.methods) { if (m.name.equals("removeSource") && m.desc.equals("(Ljava/lang/String;)V")) // trying to find paulscode.sound.Library.removeSource(String) { method = m; break; } } if (method == null) throw new RuntimeException( "Error processing " + transformedName + " - no removeSource method found"); AbstractInsnNode referenceNode = null; for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) { AbstractInsnNode insn = iterator.next(); if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") // searching for mySource.cleanup() node (line 1086) && ((MethodInsnNode) insn).name.equals("cleanup")) { referenceNode = insn; break; } } if (referenceNode != null) { LabelNode after = (LabelNode) referenceNode.getNext(); AbstractInsnNode beginning = referenceNode.getPrevious(); int varIndex = ((VarInsnNode) beginning).var; method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // adding extra if (mySource.toStream) method.instructions.insertBefore(beginning, new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "toStream", "Z")); LabelNode elseNode = new LabelNode(); method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.IFEQ, elseNode)); // if fails (else) -> go to mySource.cleanup(); method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // if (mySource.toStream) { mySource.removed = true; } method.instructions.insertBefore(beginning, new InsnNode(Opcodes.ICONST_1)); method.instructions.insertBefore(beginning, new FieldInsnNode(Opcodes.PUTFIELD, "paulscode/sound/Source", "removed", "Z")); method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.GOTO, after)); // still inside if -> jump to sourceMap.remove( sourcename ); method.instructions.insertBefore(beginning, elseNode); } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } else if (transformedName.equals("paulscode.sound.StreamThread")) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); MethodNode method = null; for (MethodNode m : classNode.methods) { if (m.name.equals("run") && m.desc.equals("()V")) // trying to find paulscode.sound.StreamThread.run(); { method = m; break; } } if (method == null) throw new RuntimeException("Error processing " + transformedName + " - no run method found"); AbstractInsnNode referenceNode = null; for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) { AbstractInsnNode insn = iterator.next(); if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("java/util/ListIterator") // searching for 'src = iter.next();' node (line 110) && ((MethodInsnNode) insn).name.equals("next")) { referenceNode = insn.getNext().getNext(); break; } } if (referenceNode != null) { int varIndex = ((VarInsnNode) referenceNode).var; LabelNode after = (LabelNode) referenceNode.getNext(); method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // add if(removed) method.instructions.insertBefore(after, new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "removed", "Z")); method.instructions.insertBefore(after, new JumpInsnNode(Opcodes.IFEQ, after)); // if the source has been marked as removed, clean it up and set the variable to null so it will be removed from the list method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // src.cleanup(); method.instructions.insertBefore(after, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "paulscode/sound/Source", "cleanup", "()V", false)); method.instructions.insertBefore(after, new InsnNode(Opcodes.ACONST_NULL)); // src = null; method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ASTORE, varIndex)); } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } return basicClass; }
From source file:net.minecraftforge.gradle.tasks.DeobfuscateJar.java
License:Open Source License
private byte[] stripSynthetics(String name, byte[] data) { ClassReader reader = new ClassReader(data); ClassNode node = new ClassNode(); reader.accept(node, 0);/*ww w .j ava2 s . c o m*/ if ((node.access & Opcodes.ACC_ENUM) == 0 && !node.superName.equals("java/lang/Enum") && (node.access & Opcodes.ACC_SYNTHETIC) == 0) { // ^^ is for ignoring enums. for (FieldNode f : ((List<FieldNode>) node.fields)) { f.access = f.access & (0xffffffff - Opcodes.ACC_SYNTHETIC); //getLogger().lifecycle("Stripping field: "+f.name); } for (MethodNode m : ((List<MethodNode>) node.methods)) { m.access = m.access & (0xffffffff - Opcodes.ACC_SYNTHETIC); //getLogger().lifecycle("Stripping method: "+m.name); } } ClassWriter writer = new ClassWriter(0); node.accept(writer); return writer.toByteArray(); }