diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java index e462e99247d6eb6bf0d2ba1c765bbd1643428f7a..890096419ef6784a27ea17b7331942f3cda9326c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java @@ -334,6 +334,15 @@ public class RootNode { return resolveClass(clsInfo); } + /** + * Searches for ClassNode by its full name (original or alias name) + * + * Warning: This method has a runtime of O(n) (n = number of classes). + * If you need to call it more than once consider {@link #buildFullAliasClassCache()} instead + * + * @param fullName + * @return + */ @Nullable public ClassNode searchClassByFullAlias(String fullName) { for (ClassNode cls : classes) { @@ -346,6 +355,24 @@ public class RootNode { return null; } + /** + * + * @return + */ + public Map buildFullAliasClassCache() { + Map classNameCache = new HashMap<>(classes.size()); + for (ClassNode cls : classes) { + ClassInfo classInfo = cls.getClassInfo(); + String fullName = classInfo.getFullName(); + String alias = classInfo.getAliasFullName(); + classNameCache.put(fullName, cls); + if (alias != null && !fullName.equals(alias)) { + classNameCache.put(alias, cls); + } + } + return classNameCache; + } + public List searchClassByShortName(String shortName) { List list = new ArrayList<>(); for (ClassNode cls : classes) { diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java index 676119226558e2e7c3508fa6e724892b4a696858..59046c66473f879d00db5647ae97a2272b94e381 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java @@ -56,6 +56,8 @@ public class BinaryXMLParser extends CommonBinaryParser { private final RootNode rootNode; private String appPackageName; + private Map classNameCache; + public BinaryXMLParser(RootNode rootNode) { this.rootNode = rootNode; try { @@ -78,7 +80,9 @@ public class BinaryXMLParser extends CommonBinaryParser { firstElement = true; decode(); nsMap = null; - return writer.finish(); + ICodeInfo codeInfo = writer.finish(); + this.classNameCache = null; // reset class name cache + return codeInfo; } private boolean isBinaryXml() throws IOException { @@ -467,6 +471,9 @@ public class BinaryXMLParser extends CommonBinaryParser { } private void attachClassNode(ICodeWriter writer, String attrName, String clsName) { + if (!writer.isMetadataSupported()) { + return; + } if (clsName == null || !attrName.equals("name")) { return; } @@ -476,7 +483,10 @@ public class BinaryXMLParser extends CommonBinaryParser { } else { clsFullName = clsName; } - ClassNode classNode = rootNode.searchClassByFullAlias(clsFullName); + if (classNameCache == null) { + classNameCache = rootNode.buildFullAliasClassCache(); + } + ClassNode classNode = classNameCache.get(clsFullName); if (classNode != null) { writer.attachAnnotation(classNode); }