List of usage examples for org.objectweb.asm.tree InsnList get
public AbstractInsnNode get(final int index)
From source file:com.android.tools.lint.client.api.LintDriver.java
License:Apache License
@Nullable private static MethodInsnNode findConstructorInvocation(@NonNull MethodNode method, @NonNull String className) { InsnList nodes = ((MethodNode) method).instructions; for (int i = 0, n = nodes.size(); i < n; i++) { AbstractInsnNode instruction = nodes.get(i); if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) { MethodInsnNode call = (MethodInsnNode) instruction; if (className.equals(call.owner)) { return call; }/*from ww w . j av a2 s .c om*/ } } return null; }
From source file:com.lion328.xenonlauncher.patcher.StringReplaceFilePatcher.java
License:Open Source License
@Override public byte[] patchFile(String name, byte[] original) { if (!name.endsWith(".class")) { return original; }/*from w w w.ja v a2s . com*/ ClassReader reader = new ClassReader(original); ClassNode node = new ClassNode(); reader.accept(node, 0); List fields = node.fields; FieldNode field; for (Object obj : fields) { if (!(obj instanceof FieldNode)) { continue; } field = (FieldNode) obj; if (field.value instanceof String) { field.value = ((String) field.value).replace(find, replace); } } List methods = node.methods; MethodNode method; for (Object obj : methods) { if (!(obj instanceof MethodNode)) { continue; } method = (MethodNode) obj; InsnList insns = method.instructions; for (int i = 0; i < insns.size(); i++) { AbstractInsnNode insn = insns.get(i); if (!(insn instanceof LdcInsnNode)) { continue; } LdcInsnNode ldc = (LdcInsnNode) insn; if (!(ldc.cst instanceof String)) { continue; } ldc.cst = ((String) ldc.cst).replace(find, replace); } } ClassWriter writer = new ClassWriter(0); node.accept(writer); return writer.toByteArray(); }
From source file:com.offbynull.coroutines.instrumenter.generators.GenericGenerators.java
License:Open Source License
/** * Combines multiple instructions in to a single instruction list. You can include normal instructions ({@link AbstractInsnNode}), * instruction lists ({@link InsnList}), or instruction generators ({@link InstructionGenerator}). * @param insns instructions/* w ww. ja v a 2s. c o m*/ * @throws NullPointerException if any argument is {@code null} or contains {@code null} * @return merged instructions */ public static InsnList merge(Object... insns) { Validate.notNull(insns); Validate.noNullElements(insns); InsnList ret = new InsnList(); for (Object insn : insns) { if (insn instanceof AbstractInsnNode) { // add single instruction AbstractInsnNode insnNode = (AbstractInsnNode) insn; ret.add(insnNode); } else if (insn instanceof InsnList) { // add instruction list InsnList insnList = (InsnList) insn; for (int i = 0; i < insnList.size(); i++) { Validate.notNull(insnList.get(i)); } ret.add((InsnList) insn); } else if (insn instanceof InstructionGenerator) { // generate conditional merger instruction list and add InsnList insnList = ((InstructionGenerator) insn).generate(); for (int i = 0; i < insnList.size(); i++) { Validate.notNull(insnList.get(i)); } ret.add(insnList); } else { // unrecognized throw new IllegalArgumentException(); } } return ret; }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
public void testReplacingThisWithOtherVariable() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); System.out.println("Donor"); printMethodNode(donorMethod);//from www . ja va 2 s.c o m //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; //make a new local variable LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin); instructionsToInject.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = donorMethod.maxLocals; donorMethod.maxLocals += type.getSize(); donorMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label instructionsToInject.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch instructionsToInject.insert(getTestBase, setRef); //replace all references to 'this' with the new variable for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } } System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<"); printMethodNode(donorMethod); String NEWCLASSNAME = "ScriptTestClass"; //write a class Class c = createClassFromClassNode(donorSource, NEWCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("before_whatDoIThinkAbout", String.class); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { "AAAA" }); System.out.println("TestDonorClass.whatDoIThinkAbout Result: " + result); assertTrue(result.equals(FIELDPROXYWORKED + "AAAA")); }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
@Test public void testInjectingIntoMethodWithLotsOfParameters() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF2); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); System.out.println("Donor Method Before Modifications:"); printMethodNode(donorMethod);/* www .j a v a 2 s . c o m*/ String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.Concatenator"; ClassNode targetSource = loadLocalClass(TARGETCLASSNAME); ClassNode exampleSource = loadLocalClass("com.triage.bytecodemaster.fortesting.JustLikeGroovyClass"); MethodNode exampleMethod = findMethod(exampleSource, "before_whatDoIThinkAbout"); System.out.println("Example Method-- Should be just like the Donor Source"); printMethodNode(exampleMethod); MethodNode targetMethod = findMethod(targetSource, "concat"); System.out.println("Target Method <Before Mods>"); printMethodNode(targetMethod); //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; InsnList targetInstructions = targetMethod.instructions; //make a new local variable in the donor method. //this variable needs to have a slot high enough that it doesnt //conflict with either the target or the source method //it will hold references to the objects we replace with 'this' LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); targetInstructions.insertBefore(targetInstructions.getFirst(), begin); targetInstructions.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = targetMethod.maxLocals; targetMethod.maxLocals += type.getSize(); targetMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label targetInstructions.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch targetInstructions.insert(getTestBase, setRef); //replace all references to 'this' in the DONOR method with the new variable //in the TARGET code for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } //remove return methods. this will prevent a return. it should cause the donor //method to have parameters that overlap with the target, which has more parameters if (node.getOpcode() == Opcodes.RETURN || node.getOpcode() == Opcodes.ARETURN) { instructionsToInject.remove(node); } } System.out.println(">>>>>>>>>Finished Modifying Donor Method <<<<<<<<"); printMethodNode(donorMethod); String NEWCLASSNAME = "ScriptTestClass"; //stash instructions at the beginning of the original method, //but after populating the new variable targetInstructions.insert(setRef, instructionsToInject); System.out.println("Modified Target:"); printMethodNode(targetMethod); //write a class Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("concat", String.class, String.class, String.class, String.class); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { "A", "B", "C", "D" }); System.out.println("Concatenator.concat Result: " + result); assertTrue(result.equals("ABCD")); }
From source file:com.triage.bytecodemaster.TestObjectReferenceSwitches.java
public void testMergedInReplacingThisWithOtherVariable() throws Exception { final String FIELDPROXYWORKED = "FIELDPROXYWORKED"; //set up the proxy object. this is the object that will receive //the proxied calls TestSubClass tcc = new TestSubClass(); tcc.setBaseString(FIELDPROXYWORKED); TestBaseClassHolder.setTestBase(tcc); //get the dynamic source that has the donor body in it ClassNode donorSource = loadGroovyTestClassAsBytecode(GROOVY_CLASS_FIELDREF); MethodNode donorMethod = findMethod(donorSource, "before_whatDoIThinkAbout"); //load the target class String TARGETCLASSNAME = "com.triage.bytecodemaster.fortesting.TestFriend"; ClassNode targetSource = loadLocalClass(TARGETCLASSNAME); MethodNode targetMethod = findMethod(targetSource, "whatDoIThinkAbout"); System.out.println("Target"); printMethodNode(targetMethod);//from w w w . ja va2 s . c o m System.out.println("Donor"); printMethodNode(donorMethod); //alright here's the strategy: (1) inject a new local variable that points // to our remote instance, // (2) inject code that sets this local to the value of a method call, // (3) change references to 'this' ( ALOAD0 or ALOAD 0 ) to ALOAD1 InsnList instructionsToInject = donorMethod.instructions; //make a new local variable LabelNode begin = new LabelNode(); LabelNode end = new LabelNode(); instructionsToInject.insertBefore(instructionsToInject.getFirst(), begin); instructionsToInject.add(end); Type type = Type.getObjectType("com/triage/bytecodemaster/fortesting/TestBaseClass"); int variableIndex = donorMethod.maxLocals; donorMethod.maxLocals += type.getSize(); donorMethod.visitLocalVariable("proxy", type.getDescriptor(), null, begin.getLabel(), end.getLabel(), variableIndex); //set the value of the local variable with a new instruction at the top //fetch a reference to our proxy object MethodInsnNode getTestBase = new MethodInsnNode(Opcodes.INVOKESTATIC, "com/triage/bytecodemaster/fortesting/TestBaseClassHolder", "getTestBase", "()Lcom/triage/bytecodemaster/fortesting/TestBaseClass;"); //insert after begin label instructionsToInject.insert(begin, getTestBase); //store reference VarInsnNode setRef = new VarInsnNode(Opcodes.ASTORE, variableIndex); //insert store after fetch instructionsToInject.insert(getTestBase, setRef); //replace all references to 'this' with the new variable for (int currentIndex = 0; currentIndex < instructionsToInject.size(); currentIndex++) { AbstractInsnNode node = instructionsToInject.get(currentIndex); if (node.getOpcode() == Opcodes.ALOAD) { VarInsnNode vin = (VarInsnNode) node; //'this' is var index 0. ours is var index varindex if (vin.var == 0) { vin.var = variableIndex; } } } System.out.println(">>>>>>>>>Finished Modifying<<<<<<<<"); printMethodNode(donorMethod); //insert the donorMethod targetMethod.instructions.insert(instructionsToInject); System.out.println(">>>>>>>>>Final Method<<<<<<<<"); printMethodNode(targetMethod); //write a class Class c = createClassFromClassNode(targetSource, TARGETCLASSNAME); Object o = c.newInstance(); Method m = o.getClass().getDeclaredMethod("whatDoIThinkAbout", TestPerson.class); TestPerson testPerson = new TestPerson(); testPerson.setName("AAAA"); //should return HAHAHA not baseStringValue String result = (String) m.invoke(o, new Object[] { testPerson }); System.out.println("TestFriend.whatDoIThinkAbout Result: " + result); assertTrue(result.equals(FIELDPROXYWORKED + "AAAA")); }
From source file:de.loskutov.bco.asm.CommentedASMifierClassVisitor.java
License:Open Source License
@Override public void visitLabel(Label label) { addIndex(-1);/* ww w. ja va2 s .c o m*/ super.visitLabel(label); InsnList instructions = currMethod.meth.instructions; LabelNode currLabel = null; for (int i = 0; i < instructions.size(); i++) { AbstractInsnNode insnNode = instructions.get(i); if (insnNode instanceof LabelNode) { LabelNode labelNode = (LabelNode) insnNode; if (labelNode.getLabel() == label) { currLabel = labelNode; } } } setCurrentLabel(currLabel); }
From source file:de.sanandrew.core.manpack.transformer.InstructionComparator.java
License:Creative Commons License
public static List<AbstractInsnNode> insnListFindEnd(InsnList haystack, InsnList needle) { LinkedList<AbstractInsnNode> callNodes = new LinkedList<>(); for (int callPoint : insnListFind(haystack, needle)) { callNodes.add(haystack.get(callPoint + needle.size() - 1)); }//ww w .j a v a 2s . c o m return callNodes; }
From source file:de.sanandrew.core.manpack.transformer.InstructionComparator.java
License:Creative Commons License
public static List<AbstractInsnNode> insnListFindStart(InsnList haystack, InsnList needle) { LinkedList<AbstractInsnNode> callNodes = new LinkedList<>(); for (int callPoint : insnListFind(haystack, needle)) { callNodes.add(haystack.get(callPoint)); }//from w ww . java2 s .c o m return callNodes; }
From source file:de.sanandrew.core.manpack.transformer.InstructionComparator.java
License:Creative Commons License
public static boolean insnListMatches(InsnList haystack, InsnList needle, int start) { if (haystack.size() - start < needle.size()) { return false; }//from w ww . j av a2s . c o m for (int i = 0; i < needle.size(); i++) { if (!insnEqual(haystack.get(i + start), needle.get(i))) { return false; } } return true; }