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

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

Introduction

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

Prototype

public AbstractInsnNode getFirst() 

Source Link

Document

Returns the first instruction in this list.

Usage

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);/*from  ww  w . ja  va 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  ww  . jav a2 s  .  co  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:com.typesafe.path_hole.PathHole.java

License:Open Source License

private static byte[] prependToClassLoader() {
    Object[] ourEnhancementsToLoadClass = getMethodNode(PathHole.class, "bytecodeToPrepend",
            "(Ljava/lang/String;Z)V");
    Object[] jlClassLoader = getMethodNode(ClassLoader.class, "loadClass",
            "(Ljava/lang/String;Z)Ljava/lang/Class;");

    // get the bytecode to prepend
    InsnList prependInst = ((MethodNode) ourEnhancementsToLoadClass[1]).instructions;

    // lets get rid of the return statement
    // remove the optional label
    if (prependInst.getLast().getOpcode() < 0) {
        prependInst.remove(prependInst.getLast());
    }// w w  w  . j av a 2 s  .c om
    // remove the return inst. It doesn't take any args so this is all we need
    prependInst.remove(prependInst.getLast());

    // now add this to loadClass method of jlClassLoader
    InsnList baseInst = ((MethodNode) jlClassLoader[1]).instructions;
    baseInst.insertBefore(baseInst.getFirst(), prependInst);

    ClassNode clClassNode = (ClassNode) jlClassLoader[0];
    //        we just need to add any fields referenced by the prepended bytecode to the jlClassLoader
    //        ClassNode prependClassNode = (ClassNode) ourEnhancementsToLoadClass[0];

    // write the new bytecode
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    clClassNode.accept(cw);
    return cw.toByteArray();
}

From source file:de.sanandrew.core.manpack.transformer.InstructionComparator.java

License:Creative Commons License

public static InsnList getImportantList(InsnList list) {
    if (list.size() == 0) {
        return list;
    }/*w  w  w .  j a  v  a2  s  .co m*/

    HashMap<LabelNode, LabelNode> labels = new HashMap<>();

    for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) {
        if (insn instanceof LabelNode) {
            labels.put((LabelNode) insn, (LabelNode) insn);
        }
    }

    InsnList importantNodeList = new InsnList();

    for (AbstractInsnNode insn = list.getFirst(); insn != null; insn = insn.getNext()) {
        if (insn instanceof LabelNode || insn instanceof LineNumberNode) {
            continue;
        }

        importantNodeList.add(insn.clone(labels));
    }
    return importantNodeList;
}

From source file:de.sanandrew.core.manpack.transformer.InstructionComparator.java

License:Creative Commons License

public static List<InsnListSection> insnListFindL(InsnList haystack, InsnList needle) {
    HashSet<LabelNode> controlFlowLabels = new HashSet<>();

    for (AbstractInsnNode insn = haystack.getFirst(); insn != null; insn = insn.getNext()) {
        switch (insn.getType()) {
        case 8://from  w w  w . j a  v a  2  s .c  o m
        case 15:
            break;
        case 7:
            JumpInsnNode jinsn = (JumpInsnNode) insn;
            controlFlowLabels.add(jinsn.label);
            break;
        case 11:
            TableSwitchInsnNode tsinsn = (TableSwitchInsnNode) insn;
            for (LabelNode label : tsinsn.labels) {
                controlFlowLabels.add(label);
            }
            break;
        case 12:
            LookupSwitchInsnNode lsinsn = (LookupSwitchInsnNode) insn;
            for (LabelNode label : lsinsn.labels) {
                controlFlowLabels.add(label);
            }
            break;
        }
    }

    LinkedList<InsnListSection> list = new LinkedList<>();

    nextsection: for (int start = 0; start <= haystack.size() - needle.size(); start++) {
        InsnListSection section = insnListMatchesL(haystack, needle, start, controlFlowLabels);
        if (section != null) {
            for (InsnListSection asection : list) {
                if (asection.last == section.last) {
                    continue nextsection;
                }
            }

            list.add(section);
        }
    }

    return list;
}

From source file:de.tuberlin.uebb.jbop.optimizer.arithmetic.ArithmeticExpressionInterpreterTest.java

License:Open Source License

/**
 * Tests that arithmeticExpressionInterpreter() of the Testobject is working correctly
 * if arithmetic Expression occur in instructions.
 *///from  w  w w  .j  a v a2s .  c o m
@Test
public void testArithmeticExpressionInterpreter() {
    // INIT
    builder.addInsn(new InsnNode(Opcodes.ICONST_1)).//
            addInsn(new InsnNode(Opcodes.ICONST_2)).//
            addInsn(new InsnNode(Opcodes.IADD)).//
            addInsn(new InsnNode(Opcodes.ICONST_1)).//
            addInsn(new InsnNode(Opcodes.ICONST_1)).//
            addInsn(new InsnNode(Opcodes.IADD)).//
            addInsn(new InsnNode(Opcodes.IADD)).//
            addInsn(new InsnNode(Opcodes.RETURN));

    // RUN STEP1
    final InsnList optimized = interpreter.optimize(builder.getMethod("testMethod").instructions,
            builder.getMethod("testMethod"));

    // ASSERT STEP 1
    assertTrue(interpreter.isOptimized());
    assertEquals(2, optimized.size());
    assertEquals(Opcodes.ICONST_5, optimized.getFirst().getOpcode());

    // RUN STEP 2
    final InsnList optimized2 = interpreter.optimize(builder.getMethod("testMethod").instructions,
            builder.getMethod("testMethod"));

    // ASSERT STEP 2
    assertFalse(interpreter.isOptimized());
    assertEquals(2, optimized2.size());
    assertEquals(Opcodes.ICONST_5, optimized2.getFirst().getOpcode());
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthInlinerTest.java

License:Open Source License

/**
 * Tests that FieldArrayLengthInliner is working correctly.
 * //  w  ww.  jav a 2  s. c o m
 * @throws Exception
 *           the exception
 */
@Test
public void testFieldArrayLengthInliner() throws Exception {
    // INIT
    final String owner = "de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthTestClass";
    final ClassNodeBuilder builder = ClassNodeBuilder.createClass(owner).//
            addField("doubleArray", "[D").withModifiers(ACC_FINAL).initArray(15).//
            addField("objectArray", Type.getDescriptor(Object[].class)).withModifiers(ACC_FINAL).initArray(23).//
            addMethod("sumArrayLength", "()I").withAnnotation(Optimizable.class).//
            addGetClassField("doubleArray").//
            addInsn(new InsnNode(Opcodes.ARRAYLENGTH)).//
            addGetClassField("objectArray").//
            addInsn(new InsnNode(Opcodes.ARRAYLENGTH)).//
            addInsn(new InsnNode(Opcodes.IADD)).//
            addInsn(new InsnNode(Opcodes.IRETURN));

    final FieldArrayLengthInliner inliner = new FieldArrayLengthInliner();
    inliner.setClassNode(builder.getClassNode());
    inliner.setInputObject(builder.toClass().instance());

    // RUN STEP 1
    final MethodNode method = builder.getMethod("sumArrayLength");
    final InsnList optimized = inliner.optimize(method.instructions, method);

    // ASSERT STEP 2
    assertEquals(4, optimized.size());
    assertEquals(15, NodeHelper.getNumberValue(optimized.getFirst()).intValue());
    assertEquals(23, NodeHelper.getNumberValue(optimized.getFirst().getNext()).intValue());
}

From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayValueInlinerTest.java

License:Open Source License

/**
 * Tests that FieldArrayValueInliner is working correctly.
 * /*w  w  w . j  av a 2s  .  co  m*/
 * @throws Exception
 *           the exception
 */
@Test
public void testFieldArrayValueInliner() throws Exception {
    // INIT
    final String owner = "de.tuberlin.uebb.jbop.optimizer.array.FieldArrayValueTestClass";
    final ClassNodeBuilder builder = ClassNodeBuilder.createClass(owner).//
            addField("doubleArray1", "[D").withAnnotation(ImmutableArray.class).initArrayWith(1.0, 2.0, 3.0).//
            addField("doubleArray2", "[D").withAnnotation(ImmutableArray.class).initArrayWith(4.0, 5.0, 6.0).//
            addMethod("sumArrayValues", "()D").withAnnotation(Optimizable.class).//
            loadFieldArrayValue("doubleArray1", 0).// 4 -> 1
            loadFieldArrayValue("doubleArray2", 0).// 4 -> 1
            addInsn(new InsnNode(Opcodes.DADD)).// 1
            loadFieldArrayValue("doubleArray1", 1).// 4 -> 1
            loadFieldArrayValue("doubleArray2", 1).// 4 -> 1
            addInsn(new InsnNode(Opcodes.DADD)).// 1
            addInsn(new InsnNode(Opcodes.DADD)).// 1
            loadFieldArrayValue("doubleArray1", 2).// 4 -> 1
            loadFieldArrayValue("doubleArray2", 2).// 4 -> 1
            addInsn(new InsnNode(Opcodes.DADD)).// 1
            addInsn(new InsnNode(Opcodes.DADD)).// 1
            addInsn(new InsnNode(Opcodes.DRETURN));// 1
    //

    final FieldArrayValueInliner inliner = new FieldArrayValueInliner();
    inliner.setClassNode(builder.getClassNode());
    inliner.setInputObject(builder.instance());

    final MethodNode method = builder.getMethod("sumArrayValues");
    assertEquals(30, method.instructions.size());

    // RUN STEP 1
    final InsnList optimized = inliner.optimize(method.instructions, method);

    // ASSERT STEP 1

    assertEquals(12, optimized.size());

    // first value pair
    AbstractInsnNode currentNode = optimized.getFirst();
    assertEquals(1.0, NodeHelper.getNumberValue(currentNode).doubleValue(), .0001);
    currentNode = currentNode.getNext();
    assertEquals(4.0, NodeHelper.getNumberValue(currentNode).doubleValue(), .0001);
    currentNode = currentNode.getNext();

    // second value pair
    currentNode = currentNode.getNext();
    assertEquals(2.0, NodeHelper.getNumberValue(currentNode).doubleValue(), .0001);
    currentNode = currentNode.getNext();
    assertEquals(5.0, NodeHelper.getNumberValue(currentNode).doubleValue(), .0001);
    currentNode = currentNode.getNext();
    currentNode = currentNode.getNext();

    // third value pair
    currentNode = currentNode.getNext();
    assertEquals(3.0, NodeHelper.getNumberValue(currentNode).doubleValue(), .0001);
    currentNode = currentNode.getNext();
    assertEquals(6.0, NodeHelper.getNumberValue(currentNode).doubleValue(), .0001);

    // RUN STEP 3
    final InsnList optimized3 = inliner.optimize(method.instructions, method);

    // ASSERT STEP 3
    assertEquals(12, optimized3.size());
}

From source file:de.tuberlin.uebb.jbop.optimizer.var.LocalVarInliner.java

License:Open Source License

/**
 * Optimize.//  www.  j  a  v  a 2s . c o  m
 * 
 * @param original
 *          the original
 * @param methodNode
 *          the method node
 * @return the insn list
 */
@Override
public InsnList optimize(final InsnList original, final MethodNode methodNode) {
    optimized = false;
    final Map<Integer, Object> knownValues = new HashMap<>();

    final AbstractInsnNode first = original.getFirst();
    final AbstractInsnNode last = original.getLast();
    handleNodes(first, last, original, knownValues, methodNode);

    return original;
}

From source file:jaspex.speculation.newspec.FlowFrame.java

License:Open Source License

/** Adiciona as frames geradas pelo Analyzer ao MethodNode, para serem usadas
  * pelo DelayGetFutureMethodVisitor.//from w w  w.  j  a  v a 2s  . c o  m
  **/
public static void injectFrames(MethodNode mn, Frame<BasicValue>[] frames) {
    InsnList insnList = mn.instructions;

    AbstractInsnNode node = insnList.getFirst();
    int pos = 0;
    while (node != null) {
        Frame<BasicValue> currentFrame = frames[pos++];
        if (currentFrame != null && !(node instanceof FrameNode)) {
            Object[] locals = locals(currentFrame);
            Object[] stack = stack(currentFrame);
            insnList.insertBefore(node, new FrameNode(F_NEW, locals.length, locals, stack.length, stack));
        }
        node = node.getNext();
    }
}