From 2eddbb9119e1796b1daa2bad9b98045519d3f03e Mon Sep 17 00:00:00 2001 From: Skylot Date: Thu, 26 Mar 2015 23:13:56 +0300 Subject: [PATCH] core: move class renaming code from ClassInfo to RenameVisitor --- .../src/main/java/jadx/core/clsp/ClsSet.java | 2 +- .../java/jadx/core/dex/info/ClassInfo.java | 17 ++++------ .../java/jadx/core/dex/nodes/ClassNode.java | 34 +++++++++++++++---- .../java/jadx/core/dex/nodes/RootNode.java | 10 +++--- .../jadx/core/dex/visitors/RenameVisitor.java | 27 ++++++++++++--- 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java b/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java index fdcf7358b..f7c12f5d1 100644 --- a/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java +++ b/jadx-core/src/main/java/jadx/core/clsp/ClsSet.java @@ -96,7 +96,7 @@ public class ClsSet { private static NClass getCls(String fullName, Map names) { NClass id = names.get(fullName); if (id == null && !names.containsKey(fullName)) { - LOG.warn("Class not found: {}", fullName); + LOG.debug("Class not found: {}", fullName); } return id; } diff --git a/jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java b/jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java index 0093e0d0d..1360c1a8e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java +++ b/jadx-core/src/main/java/jadx/core/dex/info/ClassInfo.java @@ -1,6 +1,5 @@ package jadx.core.dex.info; -import jadx.core.Consts; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.nodes.DexNode; import jadx.core.utils.exceptions.JadxRuntimeException; @@ -95,19 +94,15 @@ public final class ClassInfo { } else { parentClass = null; } - - char firstChar = clsName.charAt(0); - if (Character.isDigit(firstChar)) { - clsName = Consts.ANONYMOUS_CLASS_PREFIX + clsName; - } else if (firstChar == '$') { - clsName = "_" + clsName; - } this.name = clsName; + this.fullName = makeFullClsName(clsName); + } + + public String makeFullClsName(String shortName) { if (parentClass != null) { - this.fullName = parentClass.fullName + "." + clsName; - } else { - this.fullName = pkg.isEmpty() ? clsName : pkg + "." + clsName; + return parentClass.fullName + "." + shortName; } + return pkg.isEmpty() ? shortName : pkg + "." + shortName; } public String getFullPath() { diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java index e55606a69..8180410c4 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java @@ -112,13 +112,7 @@ public class ClassNode extends LineAttrNode implements ILoadable { int sfIdx = cls.getSourceFileIndex(); if (sfIdx != DexNode.NO_INDEX) { String fileName = dex.getString(sfIdx); - if (clsInfo != null - && !clsInfo.getFullName().contains(fileName.replace(".java", "")) - && !fileName.equals("SourceFile") - && !fileName.equals("\"")) { - this.addAttr(new SourceFileAttr(fileName)); - LOG.debug("Class '{}' compiled from '{}'", this, fileName); - } + addSourceFilenameAttr(fileName); } // restore original access flags from dalvik annotation if present @@ -225,6 +219,32 @@ public class ClassNode extends LineAttrNode implements ILoadable { } } + private void addSourceFilenameAttr(String fileName) { + if (fileName == null) { + return; + } + if (fileName.endsWith(".java")) { + fileName = fileName.substring(0, fileName.length() - 5); + } + if (fileName.isEmpty() + || fileName.equals("SourceFile") + || fileName.equals("\"")) { + return; + } + if (clsInfo != null) { + String name = clsInfo.getShortName(); + if (fileName.equals(name)) { + return; + } + if (fileName.contains("$") + && fileName.endsWith("$" + name)) { + return; + } + } + this.addAttr(new SourceFileAttr(fileName)); + LOG.debug("Class '{}' compiled from '{}'", this, fileName); + } + @Override public void load() { for (MethodNode mth : getMethods()) { 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 453f6416c..1328e8611 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 @@ -137,11 +137,11 @@ public class RootNode { public List getClasses(boolean includeInner) { List classes = new ArrayList(); - for (DexNode dexNode : dexNodes) { - for (ClassNode cls : dexNode.getClasses()) { - if (includeInner) { - classes.add(cls); - } else { + for (DexNode dex : dexNodes) { + if (includeInner) { + classes.addAll(dex.getClasses()); + } else { + for (ClassNode cls : dex.getClasses()) { if (!cls.getClassInfo().isInner()) { classes.add(cls); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java index f69b193dc..24b9463f9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java @@ -1,9 +1,11 @@ package jadx.core.dex.visitors; import jadx.api.IJadxArgs; +import jadx.core.Consts; import jadx.core.codegen.TypeGen; import jadx.core.deobf.Deobfuscator; import jadx.core.dex.attributes.AFlag; +import jadx.core.dex.info.ClassInfo; import jadx.core.dex.info.FieldInfo; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.args.ArgType; @@ -17,11 +19,8 @@ import java.io.File; import java.util.HashSet; import java.util.Set; -import org.jetbrains.annotations.NotNull; - public class RenameVisitor extends AbstractVisitor { - @NotNull private Deobfuscator deobfuscator; @Override @@ -29,9 +28,14 @@ public class RenameVisitor extends AbstractVisitor { IJadxArgs args = root.getArgs(); File deobfMapFile = new File(args.getOutDir(), "deobf_map.jobf"); deobfuscator = new Deobfuscator(args, root.getDexNodes(), deobfMapFile); - if (args.isDeobfuscationOn()) { + boolean deobfuscationOn = args.isDeobfuscationOn(); + if (deobfuscationOn) { // TODO: check classes for case sensitive names (issue #24) deobfuscator.execute(); + } else { + for (ClassNode classNode : root.getClasses(true)) { + checkClassName(classNode); + } } } @@ -45,6 +49,21 @@ public class RenameVisitor extends AbstractVisitor { return false; } + private void checkClassName(ClassNode cls) { + ClassInfo classInfo = cls.getClassInfo(); + String clsName = classInfo.getAlias().getShortName(); + String newShortName = null; + char firstChar = clsName.charAt(0); + if (Character.isDigit(firstChar)) { + newShortName = Consts.ANONYMOUS_CLASS_PREFIX + clsName; + } else if (firstChar == '$') { + newShortName = "C" + clsName; + } + if (newShortName != null) { + classInfo.rename(cls.dex(), classInfo.makeFullClsName(newShortName)); + } + } + private void checkFields(ClassNode cls) { Set names = new HashSet(); for (FieldNode field : cls.getFields()) {