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);
}
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);
}
}
}
}
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));
}
}
}
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();
}
Aggregations