Java Code Examples for org.objectweb.asm.tree.analysis.Frame#getStack()

The following examples show how to use org.objectweb.asm.tree.analysis.Frame#getStack() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FieldSetEjector.java    From radon with GNU General Public License v3.0 6 votes vote down vote up
private InsnList processFieldSet(MethodNode methodNode, Frame<AbstractValue>[] frames, Map<AbstractInsnNode, InsnList> patches, FieldInsnNode fieldInsnNode) {
    InsnList proxyArgumentFix = new InsnList();
    Frame<AbstractValue> frame = frames[methodNode.instructions.indexOf(fieldInsnNode)];

    Type type = Type.getType(fieldInsnNode.desc);
    AbstractValue argumentValue = frame.getStack(frame.getStackSize() - 1);
    if (argumentValue.isConstant() && argumentValue.getUsages().size() == 1) {
        AbstractInsnNode valueInsn = ejectorContext.isJunkArguments() ? ASMUtils.getRandomValue(type) : ASMUtils.getDefaultValue(type);
        patches.put(argumentValue.getInsnNode(), ASMUtils.singletonList(valueInsn));
        if (fieldInsnNode.getOpcode() != PUTSTATIC) {
            proxyArgumentFix.add(new VarInsnNode(ALOAD, 0));
            proxyArgumentFix.add(new TypeInsnNode(CHECKCAST, fieldInsnNode.owner));
        }
        proxyArgumentFix.add(argumentValue.getInsnNode().clone(null));
        proxyArgumentFix.add(fieldInsnNode.clone(null));
    }

    return proxyArgumentFix;
}
 
Example 2
Source File: StackThisTracker.java    From AVM with MIT License 5 votes vote down vote up
public boolean isThisTargetOfGet(int index) {
    Frame<ConstructorThisInterpreter.ThisValue> frame = this.frames[index];
    // Note that we will treat this as safe, even on invalid bytecode (we handle the stack underflow).
    int size = frame.getStackSize();
    return (size > 0)
            ? frame.getStack(size - 1).isThis
            : false;
}
 
Example 3
Source File: StackThisTracker.java    From AVM with MIT License 5 votes vote down vote up
public boolean isThisTargetOfPut(int index) {
    Frame<ConstructorThisInterpreter.ThisValue> frame = this.frames[index];
    // Note that we will treat this as safe, even on invalid bytecode (we handle the stack underflow).
    int size = frame.getStackSize();
    return (size > 1)
            ? frame.getStack(size - 2).isThis
            : false;
}
 
Example 4
Source File: FieldSetEjector.java    From radon with GNU General Public License v3.0 5 votes vote down vote up
private static Map<FieldSetInfo, List<FieldInsnNode>> analyzeFieldSets(MethodNode methodNode, Frame<AbstractValue>[] frames) {
    Map<FieldSetInfo, List<FieldInsnNode>> result = new HashMap<>();
    InsnList insnList = methodNode.instructions;
    ListIterator<AbstractInsnNode> iterator = insnList.iterator();
    while (iterator.hasNext()) {
        AbstractInsnNode abstractInsnNode = iterator.next();

        if (!(abstractInsnNode instanceof FieldInsnNode))
            continue;
        FieldInsnNode fieldInsnNode = (FieldInsnNode) abstractInsnNode;
        if (fieldInsnNode.getOpcode() != PUTFIELD && fieldInsnNode.getOpcode() != PUTSTATIC)
            continue;

        Frame<AbstractValue> frame = frames[insnList.indexOf(fieldInsnNode)];
        AbstractValue value = frame.getStack(frame.getStackSize() - 1);
        if (!value.isConstant())
            continue;

        FieldSetInfo fieldSetInfo = new FieldSetInfo(fieldInsnNode.getOpcode(), fieldInsnNode.desc);

        if (!result.containsKey(fieldSetInfo)) {
            ArrayList<FieldInsnNode> list = new ArrayList<>();
            list.add(fieldInsnNode);
            result.put(fieldSetInfo, list);
        } else {
            result.get(fieldSetInfo).add(fieldInsnNode);
        }
    }
    return result;
}
 
Example 5
Source File: MethodCallEjector.java    From radon with GNU General Public License v3.0 5 votes vote down vote up
private static Map<MethodCallInfo, List<MethodInsnNode>> analyzeMethodCalls(MethodNode methodNode, Frame<AbstractValue>[] frames) {
    Map<MethodCallInfo, List<MethodInsnNode>> result = new HashMap<>();
    InsnList insnList = methodNode.instructions;
    ListIterator<AbstractInsnNode> iterator = insnList.iterator();
    while (iterator.hasNext()) {
        AbstractInsnNode abstractInsnNode = iterator.next();

        if (!(abstractInsnNode instanceof MethodInsnNode))
            continue;
        MethodInsnNode methodInsnNode = (MethodInsnNode) abstractInsnNode;
        if ("<init>".equals(methodInsnNode.name))
            continue;

        Type[] argumentTypes = Type.getArgumentTypes(methodInsnNode.desc);
        if (argumentTypes.length == 0)
            continue;

        int constantArguments = 0;
        Frame<AbstractValue> frame = frames[insnList.indexOf(methodInsnNode)];
        for (int i = 0; i < argumentTypes.length; i++) {
            AbstractValue value = frame.getStack(frame.getStackSize() - argumentTypes.length + i);
            if (value.isConstant() && value.getUsages().size() == 1)
                constantArguments++;
        }

        if (constantArguments == 0)
            continue;

        MethodCallInfo methodCallInfo = new MethodCallInfo(methodInsnNode.owner, methodInsnNode.itf, methodInsnNode.getOpcode(), methodInsnNode.name, methodInsnNode.desc);

        if (!result.containsKey(methodCallInfo)) {
            ArrayList<MethodInsnNode> list = new ArrayList<>();
            list.add(methodInsnNode);
            result.put(methodCallInfo, list);
        } else {
            result.get(methodCallInfo).add(methodInsnNode);
        }
    }
    return result;
}
 
Example 6
Source File: SimpleStringEncryptionTransformer.java    From deobfuscator with Apache License 2.0 5 votes vote down vote up
private AbstractInsnNode getSource(MethodNode methodNode, Frame<SourceValue>[] frames, AbstractInsnNode now, int... wants) {
    Frame<SourceValue> currentFrame = frames[methodNode.instructions.indexOf(now)];
    SourceValue currentValue;

    for (int want : wants)
        if (want == now.getOpcode()) return now;
    switch (now.getOpcode()) {
        case ALOAD: {
            currentValue = currentFrame.getLocal(((VarInsnNode) now).var);
            break;
        }
        case ASTORE: {
            currentValue = currentFrame.getStack(currentFrame.getStackSize() - 1);
            break;
        }
        case DUP: {
            currentValue = currentFrame.getStack(currentFrame.getStackSize() - 1);
            break;
        }
        case PUTSTATIC: {
            currentValue = currentFrame.getStack(currentFrame.getStackSize() - 1);
            break;
        }
        case SWAP: {
            currentValue = currentFrame.getStack(currentFrame.getStackSize() - 1);
            break;
        }
        default: {
            oops("Unexpected opcode {}", now.getOpcode());
            return null;
        }
    }

    if (currentValue.insns.size() != 1) {
        oops("Expected 1 source insn, found {}", TransformerHelper.insnsToString(currentValue.insns));
        return null;
    }

    return getSource(methodNode, frames, currentValue.insns.iterator().next(), wants);
}
 
Example 7
Source File: ConstructorThisInterpreterTest.java    From AVM with MIT License 4 votes vote down vote up
@Test
public void examineTestConstructor() throws Exception {
    MethodNode node = buildTestConstructor();
    Analyzer<ConstructorThisInterpreter.ThisValue> analyzer = new Analyzer<>(new ConstructorThisInterpreter());
    Frame<ConstructorThisInterpreter.ThisValue>[] frames = analyzer.analyze(ConstructorThisInterpreterTest.class.getName(), node);
    
    // Below are the totals derived from manually inspecting the bytecode below and how we interact with it.
    int bytecodeCount = 17;
    int explicitFrameCount = 2;
    int labelCount = 2;
    Assert.assertEquals(bytecodeCount + explicitFrameCount + labelCount, frames.length);
    
    // To make this clear (since this is not obvious), we write the frame stacks.
    for (Frame<ConstructorThisInterpreter.ThisValue> frame : frames) {
        int size = frame.getStackSize();
        report(size + ": ");
        for (int i = size; i > 0; --i) {
            ConstructorThisInterpreter.ThisValue val = frame.getStack(i-1);
            String value = (null != val)
                    ? (val.isThis ? "T" : "F")
                    : "_";
            report(value);
        }
        reportLine();
    }
    
    // Now, verify the top of the stack at each bytecode.
    int index = 0;
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
    // INVOKESPECIAL
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ICONST_5
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // ILOAD
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // IF_ICMPNE
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
    // GOTO
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // (label)
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // (frame)
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // (label)
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // (frame)
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // ILOAD
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // PUTFIELD
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
    // ICONST_1
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // PUTFIELD
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // ICONST_2
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // PUTFIELD
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // RETURN
    Assert.assertEquals(frames.length, index);
}
 
Example 8
Source File: ConstructorThisInterpreterTest.java    From AVM with MIT License 4 votes vote down vote up
@Test
public void examineSecondConstructor() throws Exception {
    MethodNode node = buildSecondConstructor();
    Analyzer<ConstructorThisInterpreter.ThisValue> analyzer = new Analyzer<>(new ConstructorThisInterpreter());
    Frame<ConstructorThisInterpreter.ThisValue>[] frames = analyzer.analyze(ConstructorThisInterpreterTest.class.getName(), node);
    
    // Below are the totals derived from manually inspecting the bytecode below and how we interact with it.
    int bytecodeCount = 6;
    int explicitFrameCount = 0;
    int labelCount = 0;
    Assert.assertEquals(bytecodeCount + explicitFrameCount + labelCount, frames.length);
    
    // To make this clear (since this is not obvious), we write the frame stacks.
    for (Frame<ConstructorThisInterpreter.ThisValue> frame : frames) {
        int size = frame.getStackSize();
        report(size + ": ");
        for (int i = size; i > 0; --i) {
            ConstructorThisInterpreter.ThisValue val = frame.getStack(i-1);
            String value = (null != val)
                    ? (val.isThis ? "T" : "F")
                    : "_";
            report(value);
        }
        reportLine();
    }
    
    // Now, verify the top of the stack at each bytecode.
    int index = 0;
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
    // ALOAD
    Assert.assertEquals(false, peekStackTop(frames[index++]).isThis);
    // PUTFIELD
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // ALOAD
    Assert.assertEquals(true, peekStackTop(frames[index++]).isThis);
    // INVOKESPECIAL
    Assert.assertEquals(null, peekStackTop(frames[index++]));
    // RETURN
    Assert.assertEquals(frames.length, index);
}
 
Example 9
Source File: ConstructorThisInterpreterTest.java    From AVM with MIT License 4 votes vote down vote up
private ConstructorThisInterpreter.ThisValue peekStackTop(Frame<ConstructorThisInterpreter.ThisValue> frame) {
    int size = frame.getStackSize();
    return (size > 0)
            ? frame.getStack(size - 1)
            : null;
}
 
Example 10
Source File: OperandStackStateGenerators.java    From coroutines with GNU Lesser General Public License v3.0 4 votes vote down vote up
/**
 * Compute sizes required for the storage arrays that will contain the operand stack at this frame.
 * @param frame frame to compute for
 * @param offset the position within the operand stack to start calculating
 * @param length the number of stack items to include in calculation
 * @return size required by each storage array
 * @throws NullPointerException if any argument is {@code null}
 * @throws IllegalArgumentException if any numeric argument is negative, or if {@code offset + length} is larger than the size of the
 * operand stack
 */
public static StorageSizes computeSizes(Frame<BasicValue> frame, int offset, int length) {
    Validate.notNull(frame);
    Validate.isTrue(offset >= 0);
    Validate.isTrue(length >= 0);
    Validate.isTrue(offset < frame.getStackSize());
    Validate.isTrue(offset + length <= frame.getStackSize());
    
    // Count size required for each storage array
    int intsSize = 0;
    int longsSize = 0;
    int floatsSize = 0;
    int doublesSize = 0;
    int objectsSize = 0;
    for (int i = offset + length - 1; i >= offset; i--) {
        BasicValue basicValue = frame.getStack(i);
        Type type = basicValue.getType();
        
        // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would 'raise'
        // the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null at this
        // point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, thereby
        // keeping the same 'Lnull;' type.
        if ("Lnull;".equals(type.getDescriptor())) {
            continue;
        }
        
        switch (type.getSort()) {
            case Type.BOOLEAN:
            case Type.BYTE:
            case Type.SHORT:
            case Type.CHAR:
            case Type.INT:
                intsSize++;
                break;
            case Type.FLOAT:
                floatsSize++;
                break;
            case Type.LONG:
                longsSize++;
                break;
            case Type.DOUBLE:
                doublesSize++;
                break;
            case Type.ARRAY:
            case Type.OBJECT:
                objectsSize++;
                break;
            case Type.METHOD:
            case Type.VOID:
            default:
                throw new IllegalStateException();
        }
    }
    
    return new StorageSizes(intsSize, longsSize, floatsSize, doublesSize, objectsSize);
}
 
Example 11
Source File: InstructionModifier.java    From Bats with Apache License 2.0 3 votes vote down vote up
/**
 * Peek at a value in the current frame's stack, counting down from the top.
 *
 * @param depth how far down to peek; 0 is the top of the stack, 1 is the
 *   first element down, etc
 * @return the value on the stack, or null if it isn't a ReplacingBasciValue
 */
private ReplacingBasicValue peekFromTop(final int depth) {
  Preconditions.checkArgument(depth >= 0);
  final Frame<BasicValue> frame = list.currentFrame;
  final BasicValue basicValue = frame.getStack((frame.getStackSize() - 1) - depth);
  return filterReplacement(basicValue);
}
 
Example 12
Source File: InstructionModifier.java    From Bats with Apache License 2.0 2 votes vote down vote up
/**
 * Get the value of a function return if it is a ReplacingBasicValue.
 *
 * <p>Assumes that we're in the middle of processing an INVOKExxx instruction.
 *
 * @return the value that will be on the top of the stack after the function returns
 */
private ReplacingBasicValue getFunctionReturn() {
  final Frame<BasicValue> nextFrame = list.nextFrame;
  final BasicValue basicValue = nextFrame.getStack(nextFrame.getStackSize() - 1);
  return filterReplacement(basicValue);
}