Example usage for org.objectweb.asm.tree InsnList get

List of usage examples for org.objectweb.asm.tree InsnList get

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList get.

Prototype

public AbstractInsnNode get(final int index) 

Source Link

Document

Returns the instruction whose index is given.

Usage

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;
}