Search in sources :

Example 11 with InnerClassNode

use of org.objectweb.asm.tree.InnerClassNode in project evosuite by EvoSuite.

the class Instrumenter method transformClassNode.

@SuppressWarnings("unchecked")
public void transformClassNode(ClassNode cn, final String internalClassName) {
    if (!TransformerUtil.isClassConsideredForInstrumentation(internalClassName)) {
        logger.debug("Class {} has not been instrumented because its name is on the blacklist", internalClassName);
        return;
    }
    // consider only public and protected classes which are not interfaces
    if ((cn.access & Opcodes.ACC_INTERFACE) != 0) {
        return;
    }
    // No private
    if ((cn.access & Opcodes.ACC_PRIVATE) != 0) {
        // TODO: Why is this not detecting $DummyIntegrator?
        logger.debug("Ignoring private class {}", cn.name);
        return;
    }
    String packageName = internalClassName.replace('/', '.');
    if (packageName.contains("."))
        packageName = packageName.substring(0, packageName.lastIndexOf('.'));
    // ASM has some problem with the access of inner classes
    // so we check if the inner class name is the current class name
    // and if so, check if the inner class is actually accessible
    List<InnerClassNode> in = cn.innerClasses;
    for (InnerClassNode inc : in) {
        if (cn.name.equals(inc.name)) {
            logger.info("ASM Bug: Inner class equals class.");
            if ((inc.access & Opcodes.ACC_PROTECTED) == Opcodes.ACC_PROTECTED) {
                if (!Properties.CLASS_PREFIX.equals(packageName)) {
                    return;
                }
            }
            if ((inc.access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) {
                return;
            }
            logger.debug("Can use inner class {}", inc.name);
        }
    }
    logger.info("Checking package {} for class {}", packageName, cn.name);
    // Protected/default only if in same package
    if ((cn.access & Opcodes.ACC_PUBLIC) == 0) {
        if (!Properties.CLASS_PREFIX.equals(packageName)) {
            logger.info("Not using protected/default class because package name does not match");
            return;
        } else {
            logger.info("Using protected/default class because package name matches");
        }
    }
    /*
		if(	(cn.access & Opcodes.ACC_PUBLIC) == 0 && (cn.access & Opcodes.ACC_PROTECTED) == 0)
		{
			return;
		}
		*/
    final ArrayList<MethodNode> wrappedMethods = new ArrayList<MethodNode>();
    MethodNode methodNode;
    final Iterator<MethodNode> methodIter = cn.methods.iterator();
    while (methodIter.hasNext()) {
        methodNode = methodIter.next();
        // consider only public methods which are not abstract or native
        if (!TransformerUtil.isPrivate(methodNode.access) && !TransformerUtil.isAbstract(methodNode.access) && !TransformerUtil.isNative(methodNode.access) && !methodNode.name.equals("<clinit>")) {
            if (!TransformerUtil.isPublic(methodNode.access)) {
                // if(!Properties.CLASS_PREFIX.equals(packageName)) {
                transformWrapperCalls(methodNode);
                continue;
            // }
            }
            if (methodNode.name.equals("<init>")) {
                if (TransformerUtil.isAbstract(cn.access)) {
                    // We cannot invoke constructors of abstract classes directly
                    continue;
                }
                this.addFieldRegistryRegisterCall(methodNode);
            }
            this.instrumentPUTXXXFieldAccesses(cn, internalClassName, methodNode);
            this.instrumentGETXXXFieldAccesses(cn, internalClassName, methodNode);
            this.instrumentMethod(cn, internalClassName, methodNode, wrappedMethods);
        } else {
            transformWrapperCalls(methodNode);
        }
    }
    final int numWM = wrappedMethods.size();
    for (int i = 0; i < numWM; i++) {
        cn.methods.add(wrappedMethods.get(i));
    }
    TraceClassVisitor tcv = new TraceClassVisitor(new PrintWriter(System.err));
    cn.accept(tcv);
}
Also used : TraceClassVisitor(org.objectweb.asm.util.TraceClassVisitor) MethodNode(org.objectweb.asm.tree.MethodNode) ArrayList(java.util.ArrayList) InnerClassNode(org.objectweb.asm.tree.InnerClassNode) PrintWriter(java.io.PrintWriter)

Example 12 with InnerClassNode

use of org.objectweb.asm.tree.InnerClassNode in project dex2jar by pxb1988.

the class Dex2Asm method searchInnerClass.

/**
 * For structure
 *
 * <pre>
 * class WeAreHere {
 *     class A {
 *         class B {
 *
 *         }
 *     }
 * }
 * </pre>
 *
 * this method will add
 *
 * <pre>
 * InnerClass      Outter
 * WeAreHere$A$B   WeAreHere$A
 * WeAreHere$A     WeAreHere
 * </pre>
 *
 * to WeAreHere.class
 *
 * @param clz
 */
private static void searchInnerClass(Clz clz, List<InnerClassNode> innerClassNodes, String className) {
    Set<Clz> visited = new HashSet<>();
    Stack<Clz> stack = new Stack<>();
    stack.push(clz);
    while (!stack.empty()) {
        clz = stack.pop();
        if (visited.contains(clz)) {
            continue;
        } else {
            visited.add(clz);
        }
        if (clz.inners != null) {
            for (Clz inner : clz.inners) {
                if (inner.innerName == null) {
                    // anonymous Innerclass
                    innerClassNodes.add(new InnerClassNode(toInternalName(inner.name), null, null, clearInnerAccess(inner.access)));
                } else {
                    // non-anonymous Innerclass
                    innerClassNodes.add(new InnerClassNode(toInternalName(inner.name), toInternalName(className), inner.innerName, clearInnerAccess(inner.access)));
                }
                stack.push(inner);
            }
        }
    }
}
Also used : InnerClassNode(org.objectweb.asm.tree.InnerClassNode)

Example 13 with InnerClassNode

use of org.objectweb.asm.tree.InnerClassNode in project dex2jar by pxb1988.

the class Dex2Asm method searchEnclosing.

/**
 * For structure
 *
 * <pre>
 * class A {
 *     class B {
 *         class WeAreHere {
 *         }
 *     }
 * }
 * </pre>
 *
 * this method will add
 *
 * <pre>
 * InnerClass  Outter
 * A$B$WeAreHere A$B
 * A$B           A
 * </pre>
 *
 * to WeAreHere.class
 */
private static void searchEnclosing(Clz clz, List<InnerClassNode> innerClassNodes) {
    Set<Clz> visitedClz = new HashSet<>();
    for (Clz p = clz; p != null; p = p.enclosingClass) {
        if (!visitedClz.add(p)) {
            // prevent endless loop
            break;
        }
        Clz enclosingClass = p.enclosingClass;
        if (enclosingClass == null) {
            break;
        }
        if (enclosingClass == clz) {
            // enclosing itself, that is impossible
            break;
        }
        int accessInInner = clearInnerAccess(p.access);
        if (p.innerName != null) {
            // non-anonymous Innerclass
            innerClassNodes.add(new InnerClassNode(toInternalName(p.name), toInternalName(enclosingClass.name), p.innerName, accessInInner));
        } else {
            // anonymous Innerclass
            innerClassNodes.add(new InnerClassNode(toInternalName(p.name), null, null, accessInInner));
        }
    }
}
Also used : InnerClassNode(org.objectweb.asm.tree.InnerClassNode)

Example 14 with InnerClassNode

use of org.objectweb.asm.tree.InnerClassNode in project dex2jar by pxb1988.

the class Dex2Asm method convertClass.

public void convertClass(int dexVersion, DexClassNode classNode, ClassVisitorFactory cvf, Map<String, Clz> classes) {
    ClassVisitor cv = cvf.create(toInternalName(classNode.className));
    if (cv == null) {
        return;
    }
    // the default value of static-final field are omitted by dex, fix it
    DexFix.fixStaticFinalFieldValue(classNode);
    String signature = null;
    if (classNode.anns != null) {
        for (DexAnnotationNode ann : classNode.anns) {
            if (ann.visibility == Visibility.SYSTEM) {
                switch(ann.type) {
                    case DexConstants.ANNOTATION_SIGNATURE_TYPE:
                        {
                            Object[] strs = (Object[]) findAnnotationAttribute(ann, "value");
                            if (strs != null) {
                                StringBuilder sb = new StringBuilder();
                                for (Object str : strs) {
                                    sb.append(str);
                                }
                                signature = sb.toString();
                            }
                        }
                        break;
                }
            }
        }
    }
    String[] interfaceInterNames = null;
    if (classNode.interfaceNames != null) {
        interfaceInterNames = new String[classNode.interfaceNames.length];
        for (int i = 0; i < classNode.interfaceNames.length; i++) {
            interfaceInterNames[i] = toInternalName(classNode.interfaceNames[i]);
        }
    }
    Clz clzInfo = classes.get(classNode.className);
    int access = classNode.access;
    boolean isInnerClass = false;
    if (clzInfo != null) {
        isInnerClass = clzInfo.enclosingClass != null || clzInfo.enclosingMethod != null;
    }
    access = clearClassAccess(isInnerClass, access);
    if (isSignatureNotValid(signature, false)) {
        System.err.println("Applying workaround to class " + classNode.className + " with original signature " + signature + " by changing its signature to null.");
        signature = null;
    }
    int version = dexVersion >= DexConstants.DEX_037 ? Opcodes.V1_8 : Opcodes.V1_6;
    cv.visit(version, access, toInternalName(classNode.className), signature, classNode.superClass == null ? null : toInternalName(classNode.superClass), interfaceInterNames);
    List<InnerClassNode> innerClassNodes = new ArrayList<InnerClassNode>(5);
    if (clzInfo != null) {
        searchInnerClass(clzInfo, innerClassNodes, classNode.className);
    }
    if (isInnerClass) {
        // build Outer Clz
        if (clzInfo.innerName == null) {
            // anonymous Innerclass
            Method enclosingMethod = clzInfo.enclosingMethod;
            if (enclosingMethod != null) {
                cv.visitOuterClass(toInternalName(enclosingMethod.getOwner()), enclosingMethod.getName(), enclosingMethod.getDesc());
            } else {
                Clz enclosingClass = clzInfo.enclosingClass;
                cv.visitOuterClass(toInternalName(enclosingClass.name), null, null);
            }
        }
        searchEnclosing(clzInfo, innerClassNodes);
    }
    Collections.sort(innerClassNodes, INNER_CLASS_NODE_COMPARATOR);
    for (InnerClassNode icn : innerClassNodes) {
        if (icn.innerName != null && !isJavaIdentifier(icn.innerName)) {
            System.err.println("WARN: ignored invalid inner class name " + ", treat as anonymous inner class.");
            icn.innerName = null;
            icn.outerName = null;
        }
        icn.accept(cv);
    }
    accept(classNode.anns, cv);
    if (classNode.fields != null) {
        for (DexFieldNode fieldNode : classNode.fields) {
            convertField(classNode, fieldNode, cv);
        }
    }
    if (classNode.methods != null) {
        ClzCtx clzCtx = new ClzCtx();
        clzCtx.classDescriptor = classNode.className;
        for (DexMethodNode methodNode : classNode.methods) {
            convertMethod(classNode, methodNode, cv, clzCtx);
        }
        if (clzCtx.hexDecodeMethodNamePrefix != null) {
            addHexDecodeMethod(cv, clzCtx.hexDecodeMethodNamePrefix);
        }
    }
    cv.visitEnd();
}
Also used : IrMethod(com.googlecode.dex2jar.ir.IrMethod) InnerClassNode(org.objectweb.asm.tree.InnerClassNode)

Aggregations

InnerClassNode (org.objectweb.asm.tree.InnerClassNode)14 ArrayList (java.util.ArrayList)6 ClassNode (org.objectweb.asm.tree.ClassNode)5 MethodNode (org.objectweb.asm.tree.MethodNode)4 FieldNode (org.objectweb.asm.tree.FieldNode)3 IrMethod (com.googlecode.dex2jar.ir.IrMethod)2 PrintWriter (java.io.PrintWriter)2 TraceClassVisitor (org.objectweb.asm.util.TraceClassVisitor)2 StringWriter (java.io.StringWriter)1 Field (java.lang.reflect.Field)1 Method (java.lang.reflect.Method)1 Comparator (java.util.Comparator)1 LinkedHashSet (java.util.LinkedHashSet)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1 Set (java.util.Set)1 MethodIdentifier (org.evosuite.setup.PutStaticMethodCollector.MethodIdentifier)1 GenericAccessibleObject (org.evosuite.utils.generic.GenericAccessibleObject)1 GenericClass (org.evosuite.utils.generic.GenericClass)1 GenericConstructor (org.evosuite.utils.generic.GenericConstructor)1