Example usage for org.objectweb.asm Opcodes INVOKEDYNAMIC

List of usage examples for org.objectweb.asm Opcodes INVOKEDYNAMIC

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes INVOKEDYNAMIC.

Prototype

int INVOKEDYNAMIC

To view the source code for org.objectweb.asm Opcodes INVOKEDYNAMIC.

Click Source Link

Usage

From source file:org.apache.commons.javaflow.providers.asm4.ContinuableMethodVisitor.java

License:Apache License

public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
    mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
    visitCall(Opcodes.INVOKEDYNAMIC, desc);
}

From source file:org.evosuite.graphs.cfg.BytecodeInstructionPool.java

License:Open Source License

/**
 * Determine how many bytes the current instruction occupies together with
 * its operands//ww  w .  jav a2 s .c  o m
 * 
 * @return
 */
private int getBytecodeIncrement(AbstractInsnNode instructionNode) {
    int opcode = instructionNode.getOpcode();
    switch (opcode) {
    case Opcodes.ALOAD: // index
    case Opcodes.ASTORE: // index
    case Opcodes.DLOAD:
    case Opcodes.DSTORE:
    case Opcodes.FLOAD:
    case Opcodes.FSTORE:
    case Opcodes.ILOAD:
    case Opcodes.ISTORE:
    case Opcodes.LLOAD:
    case Opcodes.LSTORE:
        VarInsnNode varNode = (VarInsnNode) instructionNode;
        if (varNode.var > 3)
            return 1;
        else
            return 0;
    case Opcodes.BIPUSH: // byte
    case Opcodes.NEWARRAY:
    case Opcodes.RET:
        return 1;
    case Opcodes.LDC:
        LdcInsnNode ldcNode = (LdcInsnNode) instructionNode;
        if (ldcNode.cst instanceof Double || ldcNode.cst instanceof Long)
            return 2; // LDC2_W
        else
            return 1;
    case 19: //LDC_W
    case 20: //LDC2_W
        return 2;
    case Opcodes.ANEWARRAY: // indexbyte1, indexbyte2
    case Opcodes.CHECKCAST: // indexbyte1, indexbyte2
    case Opcodes.GETFIELD:
    case Opcodes.GETSTATIC:
    case Opcodes.GOTO:
    case Opcodes.IF_ACMPEQ:
    case Opcodes.IF_ACMPNE:
    case Opcodes.IF_ICMPEQ:
    case Opcodes.IF_ICMPNE:
    case Opcodes.IF_ICMPGE:
    case Opcodes.IF_ICMPGT:
    case Opcodes.IF_ICMPLE:
    case Opcodes.IF_ICMPLT:
    case Opcodes.IFLE:
    case Opcodes.IFLT:
    case Opcodes.IFGE:
    case Opcodes.IFGT:
    case Opcodes.IFNE:
    case Opcodes.IFEQ:
    case Opcodes.IFNONNULL:
    case Opcodes.IFNULL:
    case Opcodes.IINC:
    case Opcodes.INSTANCEOF:
    case Opcodes.INVOKESPECIAL:
    case Opcodes.INVOKESTATIC:
    case Opcodes.INVOKEVIRTUAL:
    case Opcodes.JSR:
    case Opcodes.NEW:
    case Opcodes.PUTFIELD:
    case Opcodes.PUTSTATIC:
    case Opcodes.SIPUSH:
        // case Opcodes.LDC_W
        // case Opcodes.LDC2_W

        return 2;
    case Opcodes.MULTIANEWARRAY:
        return 3;
    case Opcodes.INVOKEDYNAMIC:
    case Opcodes.INVOKEINTERFACE:
        return 4;

    case Opcodes.LOOKUPSWITCH:
    case Opcodes.TABLESWITCH:
        // TODO: Could be more
        return 4;
    // case Opcodes.GOTO_W 
    // case Opcodes.JSR_W
    }
    return 0;
}

From source file:org.sonar.java.bytecode.cfg.Instruction.java

License:Open Source License

@VisibleForTesting
public boolean isInvoke() {
    return Opcodes.INVOKEVIRTUAL <= opcode && opcode <= Opcodes.INVOKEDYNAMIC;
}

From source file:serianalyzer.SerianalyzerMethodVisitor.java

License:Open Source License

/**
 * {@inheritDoc}//w  w  w.j a  v a2  s.c o  m
 *
 * @see org.objectweb.asm.MethodVisitor#visitInvokeDynamicInsn(java.lang.String, java.lang.String,
 *      org.objectweb.asm.Handle, java.lang.Object[])
 */
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
    if (bsm.getTag() == Opcodes.H_INVOKESTATIC && (bsm.getName().equals("metafactory") || //$NON-NLS-1$
            bsm.getName().equals("altMetafactory")) //$NON-NLS-1$
            && bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory") && bsmArgs.length >= 2) { //$NON-NLS-1$
        Handle h = (Handle) bsmArgs[1];
        Type[] handleArgs = Type.getArgumentTypes(h.getDesc());
        Type[] formalArgs = Type.getArgumentTypes(desc);

        List<BaseType> args = this.stack.pop(formalArgs.length);
        boolean tainted = checkTainted(formalArgs, args);

        String className = Type.getObjectType(h.getOwner()).getClassName();
        boolean isStatic = h.getTag() == Opcodes.H_INVOKESTATIC;
        MethodReference r = new MethodReference(className, false, h.getName(), isStatic, h.getDesc());

        this.foundRefs.add(r);
        if (tainted) {
            if (!Arrays.equals(handleArgs, formalArgs)) {
                if (this.log.isDebugEnabled()) {
                    this.log.debug("Mismatch between formal args and handle args in " + this.ref + " " + name); //$NON-NLS-1$ //$NON-NLS-2$
                    this.log.debug("Handle arguments are " + Arrays.toString(handleArgs)); //$NON-NLS-1$
                    this.log.debug("Formal arguments are " + Arrays.toString(formalArgs)); //$NON-NLS-1$
                    this.log.debug("BSM arguments are " + Arrays.toString(bsmArgs)); //$NON-NLS-1$
                }
                this.parent.getAnalyzer().getState().getBench().unhandledLambda();
                r.setArgumentTypes(
                        setupTainting(r, Opcodes.INVOKEDYNAMIC, Collections.EMPTY_LIST, null, r, handleArgs));
            } else {
                r.setArgumentTypes(setupTainting(r, Opcodes.INVOKEDYNAMIC, args, null, r, handleArgs));
            }
            this.parent.getAnalyzer().getState().getBench().taintedCall();

            if (this.log.isDebugEnabled()) {
                this.log.debug(String.format("In %s need to check lambda %s %s::%s %s (%s): %s", //$NON-NLS-1$
                        this.ref, bsm.getTag(), bsm.getOwner(), bsm.getName(), desc, bsm.getDesc(),
                        Arrays.toString(bsmArgs)));
                this.log.debug(String.format("In %s need to check lambda %s::%s (%s)", this.ref, h.getOwner(), //$NON-NLS-1$
                        h.getName(), h.getDesc()));
                this.log.debug("Arguments " + args); //$NON-NLS-1$
            }

            boolean unsafeCall = this.parent.getAnalyzer().checkMethodCall(r, Collections.singleton(this.ref),
                    true, false);
            if (!unsafeCall) {
                this.log.debug("Call is safe"); //$NON-NLS-1$
            }
            this.foundCall = true;
        } else {
            this.parent.getAnalyzer().getState().traceCalls(r, Collections.singleton(this.ref));
            this.parent.getAnalyzer().getState().getBench().untaintedCall();
        }

        Type returnType = Type.getReturnType(desc);
        if (returnType != Type.VOID_TYPE) {
            this.stack.push(new BasicVariable(returnType, "return " + r, tainted)); //$NON-NLS-1$
        }
    } else {
        this.log.warn("Unsupported dynamic call in " + this.ref); //$NON-NLS-1$
        this.log.warn(String.format("In %s need to check lambda %s %s::%s %s (%s): %s", //$NON-NLS-1$
                this.ref, bsm.getTag(), bsm.getOwner(), bsm.getName(), desc, bsm.getDesc(),
                Arrays.toString(bsmArgs)));
    }

    super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
}

From source file:serianalyzer.SerianalyzerMethodVisitor.java

License:Open Source License

/**
 * {@inheritDoc}/* w  w w  .ja  va 2s .c om*/
 *
 * @see org.objectweb.asm.MethodVisitor#visitMethodInsn(int, java.lang.String, java.lang.String, java.lang.String,
 *      boolean)
 */
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {

    String clName = Type.getObjectType(owner).getClassName();

    if (opcode == Opcodes.INVOKESTATIC && "class$".equals(name) //$NON-NLS-1$
            && clName.equals(this.ref.getTypeNameString())) {
        // this is compiler generated for static .class references
        super.visitMethodInsn(opcode, owner, clName, desc, itf);
        return;
    }

    Type[] formalArgumentTypes = Type.getArgumentTypes(desc);
    List<BaseType> args = this.stack.pop(formalArgumentTypes.length);
    boolean tainted = checkTainted(formalArgumentTypes, args) || opcode == Opcodes.INVOKESTATIC;
    boolean fixedType = opcode == Opcodes.INVOKESTATIC || (opcode == Opcodes.INVOKESPECIAL);
    boolean deserializedTarget = false;
    Object tgt = null;

    Type tgtType = null;
    Set<Type> tgtAltTypes = null;
    if (opcode != Opcodes.INVOKESTATIC) {
        tgt = this.stack.pop();
        if (!(tgt instanceof BaseType)) {
            this.log.trace("Target not found"); //$NON-NLS-1$
            tainted = true;
        } else {
            tainted |= ((BaseType) tgt).isTainted();
            if (tgt instanceof ObjectReferenceConstant) {
                if (opcode != Opcodes.INVOKESPECIAL) {
                    clName = ((ObjectReferenceConstant) tgt).getClassName();
                }
                fixedType = true;
            }
            if (tgt instanceof SimpleType) {
                tgtType = ((SimpleType) tgt).getType();
                tgtAltTypes = ((SimpleType) tgt).getAlternativeTypes();
            }
        }
    }

    MethodReference r = new MethodReference(clName, itf, name, opcode == Opcodes.INVOKESTATIC, desc);
    r.setArgumentTypes(setupTainting(r, opcode, args, tgt, r, formalArgumentTypes));
    String realOwner = owner;
    int realOpcode = opcode;

    // optimize away doPrivileged calls, were more interested in the call target
    if ("java.security.AccessController".equals(clName) && "doPrivileged".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$
        if (this.parent.getAnalyzer().getConfig().isDumpPrivileged()) {
            this.parent.getAnalyzer().getState().reportCall(r);
            this.parent.getAnalyzer().getState().traceCalls(r, Collections.singleton(this.ref));
        }
        if (!args.isEmpty() && args.get(0) instanceof ObjectReferenceConstant) {
            ObjectReferenceConstant privAction = (ObjectReferenceConstant) args.get(0);
            String privActionClass = privAction.getClassName();
            if (this.log.isDebugEnabled()) {
                this.log.debug("Replacing doPrivileged in " + this.ref + " with " + privActionClass); //$NON-NLS-1$ //$NON-NLS-2$
            }
            r = new MethodReference(privActionClass, false, "run", false, "()Ljava/lang/Object;"); //$NON-NLS-1$//$NON-NLS-2$
            tgt = privAction;
            realOwner = privAction.getClassName();
            if (privAction.isTainted()) {
                tainted = true;
                r.taintCallee();
            }
        } else {
            if (this.log.isDebugEnabled()) {
                this.log.debug("Missing target information for doPrivileged in " + this.ref); //$NON-NLS-1$
            }
            r = new MethodReference(PrivilegedAction.class.getName(), true, "run", false, //$NON-NLS-1$
                    "()Ljava/lang/Object;"); //$NON-NLS-1$
            r.taintCallee();
            tainted = true;
            fixedType = false;
        }
        deserializedTarget = false;
        realOpcode = Opcodes.INVOKEDYNAMIC;
    }

    Type sigTgtType = Type.getObjectType(realOwner);
    if (tgtType != null && (tgtAltTypes == null || tgtAltTypes.isEmpty())) {
        try {
            Type moreConcreteType = this.parent.getAnalyzer().getMoreConcreteType(tgtType, sigTgtType);
            if (this.log.isDebugEnabled() && !moreConcreteType.equals(sigTgtType)) {
                this.log.debug(
                        "Improving target type to " + moreConcreteType + " for " + r + " in " + this.ref); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
            }
            r.setTargetType(moreConcreteType);
        } catch (SerianalyzerException e) {
            this.log.error("Failed to determine target type", e); //$NON-NLS-1$
            this.log.warn("Failing target " + tgt); //$NON-NLS-1$
            this.log.warn("Failing type " + tgtType); //$NON-NLS-1$
            this.log.warn("Signature type " + sigTgtType); //$NON-NLS-1$
            this.log.warn("In " + this.ref); //$NON-NLS-1$
            this.log.warn("Calling " + r); //$NON-NLS-1$
        }
    }

    this.foundRefs.add(r);
    if (tainted) {
        if (this.log.isDebugEnabled()) {
            this.log.debug(String.format("Tainted invoke%s method %s::%s (%s,%d,%s)", //$NON-NLS-1$
                    realOpcode == Opcodes.INVOKESTATIC ? " static" : "", //$NON-NLS-1$ //$NON-NLS-2$
                    clName, name, desc, opcode, itf));
            this.log.debug("  Arguments " + args); //$NON-NLS-1$
            if (realOpcode != Opcodes.INVOKESTATIC) {
                this.log.debug("  Target " + tgt); //$NON-NLS-1$
            }
        }
        if (tgt instanceof BaseType) {
            ((BaseType) tgt).taint();
        }
        this.parent.getAnalyzer().getState().getBench().taintedCall();

        this.parent.getAnalyzer().checkMethodCall(r, Collections.singleton(this.ref), fixedType,
                deserializedTarget);
        this.foundCall = true;
    } else {
        if (this.log.isDebugEnabled()) {
            this.log.debug(String.format("Untainted invoke%s method %s::%s (%s,%d,%s)", //$NON-NLS-1$
                    opcode == Opcodes.INVOKESTATIC ? " static" : "", //$NON-NLS-1$ //$NON-NLS-2$
                    clName, name, desc, opcode, itf));
            this.log.debug("  Arguments " + args); //$NON-NLS-1$
            if (realOpcode != Opcodes.INVOKESTATIC) {
                this.log.debug("  Target " + tgt); //$NON-NLS-1$
            }
        }
        this.parent.getAnalyzer().getState().traceCalls(r, Collections.singleton(this.ref));
        this.parent.getAnalyzer().getState().getBench().untaintedCall();
    }

    Type returnType = Type.getReturnType(desc);
    if (returnType != Type.VOID_TYPE) {
        boolean taintReturn = tainted;
        Type improvedReturnType = this.parent.getAnalyzer().getImprovedReturnType(r, fixedType,
                deserializedTarget);
        if (improvedReturnType != null) {
            if (this.log.isDebugEnabled()) {
                this.log.debug("Method " + r + " has improved return type " + improvedReturnType); //$NON-NLS-1$ //$NON-NLS-2$
            }
            returnType = improvedReturnType;
        }

        if (this.parent.getAnalyzer().getConfig().isUntaintReturn(r)) {
            taintReturn = false;
        } else if (!tainted && tgt instanceof BasicVariable) {
            if (this.log.isDebugEnabled()) {
                this.log.debug("Tainting return value for target " + tgt); //$NON-NLS-1$
            }
            taintReturn |= ((BasicVariable) tgt).isTaintReturns();
        }

        if (taintReturn) {
            this.parent.getAnalyzer().instantiable(r, returnType);
        }

        if (this.log.isDebugEnabled()) {
            this.log.debug("Return type " + returnType + (taintReturn ? " <T>" : " <U>")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
        }
        this.stack.push(new BasicVariable(returnType, "return " + r, taintReturn)); //$NON-NLS-1$
    }

    super.visitMethodInsn(opcode, owner, name, desc, itf);
}

From source file:serianalyzer.SerianalyzerMethodVisitor.java

License:Open Source License

/**
 * @param opcode//ww w .  j  a  v  a 2 s .co m
 * @param args
 * @param tgt
 * @param r
 * @param signatureTypes
 * @return
 */
private List<Type> setupTainting(MethodReference call, int opcode, List<BaseType> args, Object tgt,
        MethodReference r, Type[] signatureTypes) {
    if (opcode != Opcodes.INVOKESTATIC && opcode != Opcodes.INVOKEDYNAMIC) {
        if (tgt == null || !(tgt instanceof BaseType) || ((BaseType) tgt).isTainted()) {
            r.taintCallee();
        }
    }

    boolean foundTypes = true;
    List<Type> actualTypes = new ArrayList<>();
    if (signatureTypes.length != args.size()) {
        return null;
    }
    for (int i = 0; i < signatureTypes.length; i++) {
        Object object = args.get(i);
        if (object instanceof BaseType) {
            if (object instanceof SimpleType) {
                Type type = ((SimpleType) object).getType();
                Set<Type> altTypes = ((BaseType) object).getAlternativeTypes();

                Type sigType = signatureTypes[i];
                if (type == null) {
                    actualTypes.add(sigType);
                } else if (altTypes == null || altTypes.isEmpty()) {
                    try {
                        Type moreConcreteType = this.parent.getAnalyzer().getMoreConcreteType(type, sigType);
                        if (!moreConcreteType.equals(sigType)) {
                            // log.info("Improving type to " + moreConcreteType + " for " + call + " in " +
                            // this.ref);
                        }
                        actualTypes.add(moreConcreteType);
                    } catch (SerianalyzerException e) {
                        this.log.error("Failed to determine argument type", e); //$NON-NLS-1$
                        this.log.warn("Formal arguments are " + Arrays.toString(signatureTypes)); //$NON-NLS-1$
                        this.log.warn("Known arguments are " + args); //$NON-NLS-1$
                        this.log.warn("Failing arg " + i + ": " + object); //$NON-NLS-1$ //$NON-NLS-2$
                        this.log.warn("Failing arg type " + type); //$NON-NLS-1$
                        this.log.warn("Signature type " + sigType); //$NON-NLS-1$
                        this.log.warn("In " + this.ref); //$NON-NLS-1$
                        this.log.warn("Calling " + call); //$NON-NLS-1$
                        foundTypes = false;
                    }
                }
            } else {
                foundTypes = false;
            }

            if (((BaseType) object).isTainted()) {
                r.taintParameter(i);
            }

            if (object instanceof BasicVariable && ((BasicVariable) object).isTaintReturns()) {
                r.taintParameterReturns(i);
            }
        } else {
            r.taintParameter(i);
            foundTypes = false;
        }
    }

    if (foundTypes) {
        return actualTypes;
    }

    //
    return null;
}