public static void runAllClassesInDex(String jarCanonicalPath) throws Exception { DexFile dexFile = ArchiveReader.get(new File(jarCanonicalPath)); Set<? extends ClassDef> allClassesInDex = dexFile.getClasses(); for (ClassDef currentClass : allClassesInDex) { String normType = DexlibAdapter.getClassStringFromDex(currentClass.getType()); Translator sourceGenerator = TranslatorFactory.createTranslator(normType, new File(jarCanonicalPath)); sourceGenerator.apply(); System.out.println(sourceGenerator.toString()); } }
@Override public InterfaceInfo[] getInterfaces() { List<InterfaceInfo> result = new ArrayList<>(); for (String iface : classDef.getInterfaces()) { InterfaceInfo ii = new InterfaceInfo(); ii.interfaceStr = DexlibAdapter.getClassStringFromDex(iface); result.add(ii); } InterfaceInfo[] array = new InterfaceInfo[result.size()]; return result.toArray(array); }
@Override public FieldInfo[] getDeclaredFields() { List<FieldInfo> result = new ArrayList<>(); Iterable<? extends Field> implFields = classDef.getFields(); for (Field field : implFields) { FieldInfo fi = new FieldInfo(); fi.typeName = DexlibAdapter.getTypeName(field.getType()); fi.modifiers = field.getAccessFlags(); fi.annotations = convertAnnotations(field.getAnnotations()); fi.name = field.getName(); result.add(fi); } FieldInfo[] array = new FieldInfo[result.size()]; return result.toArray(array); }
@Override public ConstructorInfo[] getDeclaredConstructors() { Iterable<? extends Method> implConstructors = classDef.getMethods(); List<ConstructorInfo> result = new ArrayList<>(); for (Method constructor : implConstructors) { if (isConstructor(constructor)) { ConstructorInfo ci = new ConstructorInfo(); ci.parameterTypes = convertParameters(constructor.getParameters()); ci.annotations = convertAnnotations(constructor.getAnnotations()); ci.modifiers = constructor.getAccessFlags(); result.add(ci); } } ConstructorInfo[] array = new ConstructorInfo[result.size()]; return result.toArray(array); }
@Override public MethodInfo[] getDeclaredMethods() { Iterable<? extends Method> implMethods = classDef.getMethods(); List<MethodInfo> result = new ArrayList<>(); for (Method method : implMethods) { if (!isConstructor(method)) { MethodInfo mi = new MethodInfo(); mi.parameterTypes = convertParameters(method.getParameters()); mi.annotations = convertAnnotations(method.getAnnotations()); mi.modifiers = method.getAccessFlags(); mi.name = method.getName(); mi.exceptionTypes = new ExceptionInfo[0]; mi.returnType = DexlibAdapter.getTypeName(method.getReturnType()); result.add(mi); } } MethodInfo[] array = new MethodInfo[result.size()]; return result.toArray(array); }
void handleClassAnnotation(ClassDef classDef) { Set<? extends Annotation> aSet = classDef.getAnnotations(); if (aSet == null || aSet.isEmpty()) return; List<Tag> tags = handleAnnotation(aSet, classDef.getType()); if (tags == null) return; InnerClassAttribute ica = null; for (Tag t : tags) if (t != null) { if (t instanceof InnerClassTag) { if (ica == null) { // Do we already have an InnerClassAttribute? ica = (InnerClassAttribute) clazz.getTag("InnerClassAttribute"); // If not, create one if (ica == null) { ica = new InnerClassAttribute(); clazz.addTag(ica); } } ica.add((InnerClassTag) t); } else if (t instanceof VisibilityAnnotationTag) { // If a dalvik/annotation/AnnotationDefault tag is present // in a class, its AnnotationElements must be propagated // to methods through the creation of new AnnotationDefaultTag. VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t; for (AnnotationTag a : vt.getAnnotations()) { if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) { for (AnnotationElem ae : a.getElems()) { if (ae instanceof AnnotationAnnotationElem) { AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae; AnnotationTag at = aae.getValue(); // extract default elements Map<String, AnnotationElem> defaults = new HashMap<String, AnnotationElem>(); for (AnnotationElem aelem : at.getElems()) { defaults.put(aelem.getName(), aelem); } // create default tags containing default elements // and add tags on methods for (SootMethod sm : clazz.getMethods()) { String methodName = sm.getName(); if (defaults.containsKey(methodName)) { AnnotationElem e = defaults.get(methodName); // Okay, the name is the same, but is it actually the same type? Type annotationType = getSootType(e); boolean isCorrectType = false; if (annotationType == null) { // we do not know the type of the annotation, so we guess it's the correct // type. isCorrectType = true; } else { if (annotationType.equals(sm.getReturnType())) { isCorrectType = true; } else if (annotationType.equals(ARRAY_TYPE)) { if (sm.getReturnType() instanceof ArrayType) isCorrectType = true; } } if (isCorrectType && sm.getParameterCount() == 0) { e.setName("default"); AnnotationDefaultTag d = new AnnotationDefaultTag(e); sm.addTag(d); // In case there is more than one matching method, we only use the first one defaults.remove(sm.getName()); } } } for (Entry<String, AnnotationElem> leftOverEntry : defaults.entrySet()) { // We were not able to find a matching method for the tag, because the return // signature // does not match SootMethod found = clazz.getMethodByNameUnsafe(leftOverEntry.getKey()); AnnotationElem element = leftOverEntry.getValue(); if (found != null) { element.setName("default"); AnnotationDefaultTag d = new AnnotationDefaultTag(element); found.addTag(d); } } } } } } if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE)) clazz.addTag(vt); } else { clazz.addTag(t); } Debug.printDbg("add class annotation: ", t, " type: ", t.getClass()); } }
@Override public String getName() { return DexlibAdapter.getClassStringFromDex(classDef.getType()); }
@Override public String getSuperclass() { return DexlibAdapter.getClassStringFromDex(classDef.getSuperclass()); }
@Override public int getModifiers() { return classDef.getAccessFlags(); }
@Override public AnnotationInfo[] getAnnotations() { return convertAnnotations(classDef.getAnnotations()); }