diff --git a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java index a1cbd82d3..a523afb83 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/ClassGen.java @@ -36,7 +36,6 @@ import jadx.core.utils.CodegenUtils; import jadx.core.utils.ErrorsCounter; import jadx.core.utils.Utils; import jadx.core.utils.exceptions.CodegenException; -import jadx.core.utils.exceptions.JadxRuntimeException; public class ClassGen { @@ -84,14 +83,14 @@ public class ClassGen { int importsCount = imports.size(); if (importsCount != 0) { List sortedImports = new ArrayList<>(imports); - sortedImports.sort(Comparator.comparing(classInfo -> classInfo.getAlias().getFullName())); + sortedImports.sort(Comparator.comparing(ClassInfo::getAliasFullName)); sortedImports.forEach(classInfo -> { clsCode.startLine("import "); ClassNode classNode = cls.root().resolveClass(classInfo); if (classNode != null) { clsCode.attachAnnotation(classNode); } - clsCode.add(classInfo.getAlias().getFullName()); + clsCode.add(classInfo.getAliasFullName()); clsCode.add(';'); }); clsCode.newLine(); @@ -123,7 +122,7 @@ public class ClassGen { } // 'static' and 'private' modifier not allowed for top classes (not inner) - if (!cls.getAlias().isInner()) { + if (!cls.getClassInfo().isInner()) { af = af.remove(AccessFlags.ACC_STATIC).remove(AccessFlags.ACC_PRIVATE); } @@ -142,7 +141,7 @@ public class ClassGen { clsCode.add("class "); } clsCode.attachDefinition(cls); - clsCode.add(cls.getAlias().getShortName()); + clsCode.add(cls.getClassInfo().getAliasShortName()); addGenericMap(clsCode, cls.getGenericMap(), true); clsCode.add(' '); @@ -200,7 +199,9 @@ public class ClassGen { code.add(g.getObject()); } else { useClass(code, g); - if (classDeclaration && !cls.getAlias().isInner()) { + if (classDeclaration + && !cls.getClassInfo().isInner() + && cls.root().getArgs().isUseImports()) { addImport(ClassInfo.fromType(cls.root(), g)); } } @@ -507,11 +508,11 @@ public class ClassGen { } private String useClassInternal(ClassInfo useCls, ClassInfo extClsInfo) { - String fullName = extClsInfo.getAlias().makeFullName(); + String fullName = extClsInfo.getAliasFullName(); if (fallback || !useImports) { return fullName; } - String shortName = extClsInfo.getAlias().getShortName(); + String shortName = extClsInfo.getAliasShortName(); if (extClsInfo.getPackage().equals("java.lang") && extClsInfo.getParentClass() == null) { return shortName; } @@ -537,12 +538,12 @@ public class ClassGen { if (extClsInfo.isDefaultPackage()) { return shortName; } - if (extClsInfo.getAlias().getPackage().equals(useCls.getAlias().getPackage())) { - fullName = extClsInfo.getAlias().getNameWithoutPackage(); + if (extClsInfo.getAliasPkg().equals(useCls.getAliasPkg())) { + fullName = extClsInfo.getAliasNameWithoutPackage(); } for (ClassInfo importCls : getImports()) { if (!importCls.equals(extClsInfo) - && importCls.getAlias().getShortName().equals(shortName)) { + && importCls.getAliasShortName().equals(shortName)) { if (extClsInfo.isInner()) { String parent = useClassInternal(useCls, extClsInfo.getParentClass()); return parent + '.' + shortName; @@ -559,9 +560,6 @@ public class ClassGen { if (parentGen != null) { parentGen.addImport(classInfo); } else { - if (classInfo.isAlias()) { - throw new JadxRuntimeException("Don't add aliases class info to import list: " + classInfo); - } imports.add(classInfo); } } @@ -596,15 +594,15 @@ public class ClassGen { if (useCls == null) { return false; } - String shortName = searchCls.getAlias().getShortName(); - if (useCls.getAlias().getShortName().equals(shortName)) { + String shortName = searchCls.getAliasShortName(); + if (useCls.getAliasShortName().equals(shortName)) { return true; } ClassNode classNode = dex.resolveClass(useCls); if (classNode != null) { for (ClassNode inner : classNode.getInnerClasses()) { - if (inner.getAlias().getShortName().equals(shortName) - && !inner.getAlias().equals(searchCls.getAlias())) { + if (inner.getShortName().equals(shortName) + && !inner.getFullName().equals(searchCls.getAliasFullName())) { return true; } } @@ -621,7 +619,7 @@ public class ClassGen { private void insertRenameInfo(CodeWriter code, ClassNode cls) { ClassInfo classInfo = cls.getClassInfo(); - if (classInfo.isRenamed()) { + if (classInfo.hasAlias()) { code.startLine("/* renamed from: ").add(classInfo.getType().getObject()).add(" */"); } } diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 377eb38d0..f871c70f0 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -653,7 +653,7 @@ public class InsnGen { break; case STATIC: - ClassInfo insnCls = mth.getParentClass().getAlias(); + ClassInfo insnCls = mth.getParentClass().getClassInfo(); ClassInfo declClass = callMth.getDeclClass(); if (!insnCls.equals(declClass)) { useClass(code, declClass); @@ -673,7 +673,7 @@ public class InsnGen { @Nullable private ClassInfo getClassForSuperCall(CodeWriter code, MethodInfo callMth) { ClassNode useCls = mth.getParentClass(); - ClassInfo insnCls = useCls.getAlias(); + ClassInfo insnCls = useCls.getClassInfo(); ClassInfo declClass = callMth.getDeclClass(); if (insnCls.equals(declClass)) { return null; diff --git a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java index a4e0ba052..e2d690ca1 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/MethodGen.java @@ -187,7 +187,7 @@ public class MethodGen { code.startLine("*/"); code.startLine("throw new UnsupportedOperationException(\"Method not decompiled: ") - .add(mth.getParentClass().getAlias().makeFullName()) + .add(mth.getParentClass().getClassInfo().getAliasFullName()) .add('.') .add(mth.getAlias()) .add('(') diff --git a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java index 701142176..b8dd224fe 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java @@ -65,7 +65,7 @@ public class NameGen { varNames.add(field.getAlias()); } for (ClassNode innerClass : parentClass.getInnerClasses()) { - varNames.add(innerClass.getAlias().getShortName()); + varNames.add(innerClass.getClassInfo().getAliasShortName()); } // add all root package names to avoid collisions with full class names varNames.addAll(mth.root().getCacheStorage().getRootPkgs()); @@ -259,10 +259,10 @@ public class NameGen { if (name.startsWith("get") || name.startsWith("set")) { return fromName(name.substring(3)); } - ArgType declType = callMth.getDeclClass().getAlias().getType(); if ("iterator".equals(name)) { return "it"; } + ArgType declType = callMth.getDeclClass().getType(); if ("toString".equals(name)) { return makeNameForType(declType); } diff --git a/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java b/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java index 210f0b40d..19a9357a6 100644 --- a/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java +++ b/jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -43,7 +44,7 @@ public class Deobfuscator { private final List dexNodes; private final DeobfPresets deobfPresets; - private final Map clsMap = new HashMap<>(); + private final Map clsMap = new LinkedHashMap<>(); private final Map fldMap = new HashMap<>(); private final Map mthMap = new HashMap<>(); @@ -230,9 +231,19 @@ public class Deobfuscator { return; } ClassInfo clsInfo = cls.getClassInfo(); - String fullName = getClassFullName(clsInfo); - if (!fullName.equals(clsInfo.getFullName())) { - clsInfo.rename(cls.root(), fullName); + DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo); + if (deobfClsInfo != null) { + clsInfo.changeShortName(deobfClsInfo.getAlias()); + PackageNode pkgNode = deobfClsInfo.getPkg(); + if (!clsInfo.isInner() && pkgNode.hasAnyAlias()) { + clsInfo.changePkg(pkgNode.getFullAlias()); + } + } else if (!clsInfo.isInner()) { + // check if package renamed + PackageNode pkgNode = getPackageNode(clsInfo.getPackage(), false); + if (pkgNode.hasAnyAlias()) { + clsInfo.changePkg(pkgNode.getFullAlias()); + } } for (FieldNode field : cls.getFields()) { if (field.contains(AFlag.DONT_RENAME)) { @@ -397,7 +408,7 @@ public class Deobfuscator { } else if (name.endsWith(".kt")) { name = name.substring(0, name.length() - ".kt".length()); } - if (!NameMapper.isValidIdentifier(name) || NameMapper.isReserved(name)) { + if (!NameMapper.isValidIdentifier(name) || !NameMapper.isAllCharsPrintable(name)) { return null; } for (DeobfClsInfo deobfClsInfo : clsMap.values()) { @@ -405,7 +416,7 @@ public class Deobfuscator { return null; } } - ClassNode otherCls = cls.dex().root().searchClassByName(cls.getPackage() + '.' + name); + ClassNode otherCls = cls.root().searchClassByName(cls.getPackage() + '.' + name); if (otherCls != null) { return null; } @@ -537,10 +548,7 @@ public class Deobfuscator { } private String getClassFullName(ClassNode cls) { - return getClassFullName(cls.getClassInfo()); - } - - private String getClassFullName(ClassInfo clsInfo) { + ClassInfo clsInfo = cls.getClassInfo(); DeobfClsInfo deobfClsInfo = clsMap.get(clsInfo); if (deobfClsInfo != null) { return deobfClsInfo.getFullName(); diff --git a/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java b/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java index 20cf57389..bb13326f9 100644 --- a/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java +++ b/jadx-core/src/main/java/jadx/core/deobf/NameMapper.java @@ -126,7 +126,7 @@ public class NameMapper { *

*/ public static String removeInvalidCharsMiddle(String name) { - if (isValidIdentifier(name)) { + if (isValidIdentifier(name) && isAllCharsPrintable(name)) { return name; } int len = name.length(); diff --git a/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java b/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java index bfa5206b1..e5fd1debc 100644 --- a/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java +++ b/jadx-core/src/main/java/jadx/core/deobf/PackageNode.java @@ -58,6 +58,16 @@ public class PackageNode { return packageAlias != null; } + public boolean hasAnyAlias() { + if (hasAlias()) { + return true; + } + if (parentPackage != this) { + return parentPackage.hasAnyAlias(); + } + return false; + } + public String getFullAlias() { if (cachedPackageFullAlias == null) { Deque pp = getParentPackages(); diff --git a/jadx-core/src/main/java/jadx/core/dex/info/ClassAliasInfo.java b/jadx-core/src/main/java/jadx/core/dex/info/ClassAliasInfo.java new file mode 100644 index 000000000..9c02718ef --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/info/ClassAliasInfo.java @@ -0,0 +1,39 @@ +package jadx.core.dex.info; + +import org.jetbrains.annotations.Nullable; + +class ClassAliasInfo { + private final String shortName; + @Nullable + private final String pkg; + @Nullable + private String fullName; + + ClassAliasInfo(@Nullable String pkg, String shortName) { + this.pkg = pkg; + this.shortName = shortName; + } + + @Nullable + public String getPkg() { + return pkg; + } + + public String getShortName() { + return shortName; + } + + @Nullable + public String getFullName() { + return fullName; + } + + public void setFullName(@Nullable String fullName) { + this.fullName = fullName; + } + + @Override + public String toString() { + return "Alias{" + shortName + ", pkg=" + pkg + ", fullName=" + fullName + '}'; + } +} 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 3c8f4cb86..7e166566f 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 @@ -12,48 +12,42 @@ import jadx.core.dex.nodes.RootNode; import jadx.core.utils.exceptions.JadxRuntimeException; public final class ClassInfo implements Comparable { - private final ArgType type; - private String pkg; private String name; + @Nullable("for inner classes") + private String pkg; private String fullName; - // for inner class not equals null + @Nullable private ClassInfo parentClass; - // class info after rename (deobfuscation) - private ClassInfo alias; - - private ClassInfo(ArgType type) { - this.type = checkClassType(type); - this.alias = this; - } - - private ClassInfo(RootNode root, ArgType type) { - this(root, type, true); - } + @Nullable + private ClassAliasInfo alias; private ClassInfo(RootNode root, ArgType type, boolean inner) { - this(type); + this.type = type; splitAndApplyNames(root, type, inner); } - private ClassInfo(ArgType type, String pkg, String name, @Nullable ClassInfo parentClass) { - this(type); - this.pkg = pkg; - this.name = name; - this.parentClass = parentClass; - this.fullName = makeFullClsName(name, false); - } - public static ClassInfo fromType(RootNode root, ArgType type) { ArgType clsType = checkClassType(type); ClassInfo cls = root.getInfoStorage().getCls(clsType); if (cls != null) { return cls; } - ClassInfo newClsInfo = new ClassInfo(root, clsType); + ClassInfo newClsInfo = new ClassInfo(root, clsType, true); return root.getInfoStorage().putCls(newClsInfo); } + public static ClassInfo fromDex(DexNode dex, int clsIndex) { + if (clsIndex == DexNode.NO_INDEX) { + return null; + } + return fromType(dex.root(), dex.getType(clsIndex)); + } + + public static ClassInfo fromName(RootNode root, String clsName) { + return fromType(root, ArgType.object(clsName)); + } + private static ArgType checkClassType(ArgType type) { if (type == null) { throw new JadxRuntimeException("Null class type"); @@ -71,135 +65,164 @@ public final class ClassInfo implements Comparable { return type; } - public static ClassInfo fromDex(DexNode dex, int clsIndex) { - if (clsIndex == DexNode.NO_INDEX) { - return null; - } - return fromType(dex.root(), dex.getType(clsIndex)); - } - - public static ClassInfo fromName(RootNode root, String clsName) { - return fromType(root, ArgType.object(clsName)); - } - - public void rename(RootNode root, String fullName) { - if (!alias.makeFullName().equals(fullName)) { - ClassInfo newAlias = new ClassInfo(type); - newAlias.splitAndApplyNames(root, fullName, isInner()); - newAlias.alias = null; - this.alias = newAlias; - } - } - - public void renameShortName(String aliasName) { + public void changeShortName(String aliasName) { if (!Objects.equals(name, aliasName)) { - ClassInfo newAlias = new ClassInfo(type, alias.pkg, aliasName, parentClass); - newAlias.alias = null; + ClassAliasInfo newAlias = new ClassAliasInfo(getAliasPkg(), aliasName); + fillAliasFullName(newAlias); this.alias = newAlias; } } - public void renamePkg(String aliasPkg) { - if (!Objects.equals(pkg, aliasPkg)) { - ClassInfo newAlias = new ClassInfo(type, aliasPkg, alias.name, parentClass); - newAlias.alias = null; + public void changePkg(String aliasPkg) { + if (isInner()) { + throw new JadxRuntimeException("Can't change package for inner class"); + } + if (!Objects.equals(getAliasPkg(), aliasPkg)) { + ClassAliasInfo newAlias = new ClassAliasInfo(aliasPkg, getAliasShortName()); + fillAliasFullName(newAlias); this.alias = newAlias; } } - public boolean isRenamed() { - return alias != this; + private void fillAliasFullName(ClassAliasInfo alias) { + if (parentClass == null) { + alias.setFullName(makeFullClsName(alias.getPkg(), alias.getShortName(), null, true, false)); + } } - public ClassInfo getAlias() { - return alias == null ? this : alias; + public String getAliasPkg() { + if (isInner()) { + return parentClass.getAliasPkg(); + } + return alias == null ? getPackage() : alias.getPkg(); } - public boolean isAlias() { - return alias == null; + public String getAliasShortName() { + return alias == null ? getShortName() : alias.getShortName(); + } + + public String getAliasFullName() { + if (alias != null) { + String aliasFullName = alias.getFullName(); + if (aliasFullName == null) { + return makeAliasFullName(); + } + return aliasFullName; + } + if (parentClass != null && parentClass.hasAlias()) { + return makeAliasFullName(); + } + return getFullName(); + } + + public boolean hasAlias() { + if (alias != null) { + return true; + } + return parentClass != null && parentClass.hasAlias(); } private void splitAndApplyNames(RootNode root, ArgType type, boolean canBeInner) { - splitAndApplyNames(root, type.getObject(), canBeInner); - } - - private void splitAndApplyNames(RootNode root, String fullObjectName, boolean canBeInner) { + String fullObjectName = type.getObject(); + String clsPkg; String clsName; int dot = fullObjectName.lastIndexOf('.'); if (dot == -1) { - pkg = ""; + clsPkg = ""; clsName = fullObjectName; } else { - pkg = fullObjectName.substring(0, dot); + clsPkg = fullObjectName.substring(0, dot); clsName = fullObjectName.substring(dot + 1); } int sep = clsName.lastIndexOf('$'); if (canBeInner && sep > 0 && sep != clsName.length() - 1) { - String parClsName = pkg + '.' + clsName.substring(0, sep); - if (pkg.isEmpty()) { + String parClsName = clsPkg + '.' + clsName.substring(0, sep); + if (clsPkg.isEmpty()) { parClsName = clsName.substring(0, sep); } - + pkg = null; parentClass = fromName(root, parClsName); clsName = clsName.substring(sep + 1); } else { + pkg = clsPkg; parentClass = null; } this.name = clsName; - this.fullName = makeFullClsName(clsName, false); + this.fullName = makeFullName(); } - private String makeFullClsName(String shortName, boolean raw) { + private static String makeFullClsName(String pkg, String shortName, ClassInfo parentClass, boolean alias, boolean raw) { if (parentClass != null) { String innerSep = raw ? "$" : "."; - return parentClass.makeFullClsName(parentClass.getShortName(), raw) + innerSep + shortName; + String parentFullName; + if (alias) { + parentFullName = raw ? parentClass.makeAliasRawFullName() : parentClass.getAliasFullName(); + } else { + parentFullName = raw ? parentClass.makeRawFullName() : parentClass.getFullName(); + } + return parentFullName + innerSep + shortName; } return pkg.isEmpty() ? shortName : pkg + '.' + shortName; } - public String makeFullName() { - return makeFullClsName(this.name, false); + private String makeFullName() { + return makeFullClsName(pkg, name, parentClass, false, false); } public String makeRawFullName() { - return makeFullClsName(this.name, true); + return makeFullClsName(pkg, name, parentClass, false, true); } - public String getFullPath() { - ClassInfo usedAlias = getAlias(); - return usedAlias.getPackage().replace('.', File.separatorChar) + private String makeAliasFullName() { + return makeFullClsName(getAliasPkg(), getAliasShortName(), parentClass, true, false); + } + + private String makeAliasRawFullName() { + return makeFullClsName(pkg, name, parentClass, true, true); + } + + public String getAliasFullPath() { + return getAliasPkg().replace('.', File.separatorChar) + File.separatorChar - + usedAlias.getNameWithoutPackage().replace('.', '_'); + + getAliasNameWithoutPackage().replace('.', '_'); } public String getFullName() { - return makeFullName(); + return fullName; } public String getShortName() { return name; } + @NotNull public String getPackage() { + if (parentClass != null) { + return parentClass.getPackage(); + } + if (pkg == null) { + throw new JadxRuntimeException("Package is null for not inner class"); + } return pkg; } public boolean isDefaultPackage() { - return pkg.isEmpty(); + return getPackage().isEmpty(); } public String getRawName() { return type.getObject(); } - public String getNameWithoutPackage() { + public String getAliasNameWithoutPackage() { if (parentClass == null) { - return name; + return getAliasShortName(); } - return parentClass.getNameWithoutPackage() + '.' + name; + return parentClass.getAliasNameWithoutPackage() + '.' + getAliasShortName(); } + @Nullable public ClassInfo getParentClass() { return parentClass; } @@ -231,7 +254,7 @@ public final class ClassInfo implements Comparable { @Override public String toString() { - return makeFullName(); + return getFullName(); } @Override @@ -253,6 +276,6 @@ public final class ClassInfo implements Comparable { @Override public int compareTo(@NotNull ClassInfo o) { - return fullName.compareTo(o.fullName); + return getFullName().compareTo(o.getFullName()); } } 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 bc54922d5..74542b1e1 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 @@ -459,23 +459,16 @@ public class ClassNode extends LineAttrNode implements ILoadable, ICodeNode { return clsInfo; } - /** - * Class info for external usage (code generation and external api). - */ - public ClassInfo getAlias() { - return clsInfo.getAlias(); - } - public String getShortName() { - return clsInfo.getAlias().getShortName(); + return clsInfo.getAliasShortName(); } public String getFullName() { - return clsInfo.getAlias().getFullName(); + return clsInfo.getAliasFullName(); } public String getPackage() { - return clsInfo.getAlias().getPackage(); + return clsInfo.getAliasPkg(); } public void setCode(CodeWriter code) { diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java index 3113570b1..6045c03e5 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java @@ -25,7 +25,6 @@ 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; -import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.core.utils.files.DexFile; public class DexNode implements IDexNode { @@ -95,9 +94,6 @@ public class DexNode implements IDexNode { @Nullable ClassNode resolveClassLocal(ClassInfo clsInfo) { - if (clsInfo.isAlias()) { - throw new JadxRuntimeException("Don't resolve class by alias: " + clsInfo); - } return clsMap.get(clsInfo); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java index 301062339..7c9207f04 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java @@ -116,7 +116,7 @@ public class DotGraphVisitor extends AbstractVisitor { + (useRegions ? ".regions" : "") + (rawInsn ? ".raw" : "") + ".dot"; - dot.save(dir, mth.getParentClass().getClassInfo().getFullPath() + "_graphs", fileName); + dot.save(dir, mth.getParentClass().getClassInfo().getAliasFullPath() + "_graphs", fileName); } private void processMethodRegion(MethodNode mth) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java b/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java index c1e9dd698..a57d4cd86 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java @@ -154,7 +154,8 @@ public class PrepareForCodeGen extends AbstractVisitor { private static void modifyArith(BlockNode block) { List list = block.getInstructions(); for (InsnNode insn : list) { - if (insn.getType() == InsnType.ARITH) { + if (insn.getType() == InsnType.ARITH + && !insn.contains(AFlag.DECLARE_VAR)) { // TODO: move this modify before ProcessVariable RegisterArg res = insn.getResult(); InsnArg arg = insn.getArg(0); boolean replace = false; 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 53f509845..54f5d383e 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 @@ -59,11 +59,10 @@ public class RenameVisitor extends AbstractVisitor { Set clsFullPaths = new HashSet<>(classes.size()); for (ClassNode cls : classes) { ClassInfo clsInfo = cls.getClassInfo(); - ClassInfo aliasClsInfo = clsInfo.getAlias(); - if (!clsFullPaths.add(aliasClsInfo.getFullPath().toLowerCase())) { + if (!clsFullPaths.add(clsInfo.getAliasFullPath().toLowerCase())) { String newShortName = deobfuscator.getClsAlias(cls); - clsInfo.renameShortName(newShortName); - clsFullPaths.add(clsInfo.getAlias().getFullPath().toLowerCase()); + clsInfo.changeShortName(newShortName); + clsFullPaths.add(clsInfo.getAliasFullPath().toLowerCase()); } } } @@ -72,14 +71,28 @@ public class RenameVisitor extends AbstractVisitor { private void checkClassName(ClassNode cls, JadxArgs args) { ClassInfo classInfo = cls.getClassInfo(); - String clsName = classInfo.getAlias().getShortName(); + String clsName = classInfo.getAliasShortName(); String newShortName = fixClsShortName(args, clsName); if (!newShortName.equals(clsName)) { - classInfo.renameShortName(newShortName); + classInfo.changeShortName(newShortName); } - if (classInfo.getAlias().getPackage().isEmpty()) { - classInfo.renamePkg(Consts.DEFAULT_PACKAGE_NAME); + if (args.isRenameValid()) { + if (classInfo.isInner()) { + ClassInfo parentClass = classInfo.getParentClass(); + while (parentClass != null) { + if (parentClass.getAliasShortName().equals(clsName)) { + String clsAlias = deobfuscator.getClsAlias(cls); + classInfo.changeShortName(clsAlias); + break; + } + parentClass = parentClass.getParentClass(); + } + } else { + if (classInfo.getAliasPkg().isEmpty()) { + classInfo.changePkg(Consts.DEFAULT_PACKAGE_NAME); + } + } } } @@ -157,7 +170,7 @@ public class RenameVisitor extends AbstractVisitor { private static Set collectRootPkgs(List classes) { Set fullPkgs = new HashSet<>(); for (ClassNode cls : classes) { - fullPkgs.add(cls.getAlias().getPackage()); + fullPkgs.add(cls.getClassInfo().getAliasPkg()); } Set rootPkgs = new HashSet<>(); for (String pkg : fullPkgs) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java b/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java index 001e6e755..b51fe54cf 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java @@ -21,7 +21,7 @@ public class SaveCode { if (clsCode == null) { throw new JadxRuntimeException("Code not generated for class " + cls.getFullName()); } - String fileName = cls.getClassInfo().getFullPath() + ".java"; + String fileName = cls.getClassInfo().getAliasFullPath() + ".java"; if (args.isFallbackMode()) { fileName += ".jadx"; } diff --git a/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java b/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java index b94f880bc..9c85299ed 100644 --- a/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java +++ b/jadx-core/src/main/java/jadx/core/utils/android/AndroidResourcesUtils.java @@ -74,7 +74,7 @@ public class AndroidResourcesUtils { if (parentClass != null && parentClass.getShortName().equals("R")) { clsGen.useClass(code, parentClass); code.add('.'); - code.add(declClass.getAlias().getShortName()); + code.add(declClass.getAliasShortName()); return true; } return false; diff --git a/jadx-core/src/main/java/jadx/core/xmlgen/XmlDeobf.java b/jadx-core/src/main/java/jadx/core/xmlgen/XmlDeobf.java index a31092ae3..4e3942a57 100644 --- a/jadx-core/src/main/java/jadx/core/xmlgen/XmlDeobf.java +++ b/jadx-core/src/main/java/jadx/core/xmlgen/XmlDeobf.java @@ -3,6 +3,7 @@ package jadx.core.xmlgen; import java.util.HashMap; import java.util.Map; +import jadx.core.dex.info.ClassInfo; import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.RootNode; @@ -28,9 +29,10 @@ public class XmlDeobf { private static String getNewClassName(RootNode rootNode, String old) { if (DEOBF_MAP.isEmpty()) { for (ClassNode classNode : rootNode.getClasses(true)) { - if (classNode.getAlias() != null) { - String oldName = classNode.getClassInfo().getFullName(); - String newName = classNode.getAlias().getFullName(); + ClassInfo classInfo = classNode.getClassInfo(); + if (classInfo.hasAlias()) { + String oldName = classInfo.getFullName(); + String newName = classInfo.getAliasFullName(); if (!oldName.equals(newName)) { DEOBF_MAP.put(oldName, newName); }