Commit c555cd08 authored by Skylot's avatar Skylot

fix: rename packages with reserved names (#711)

parent 92e28326
...@@ -346,7 +346,7 @@ public class Deobfuscator { ...@@ -346,7 +346,7 @@ public class Deobfuscator {
ClassInfo classInfo = cls.getClassInfo(); ClassInfo classInfo = cls.getClassInfo();
String pkgFullName = classInfo.getPackage(); String pkgFullName = classInfo.getPackage();
PackageNode pkg = getPackageNode(pkgFullName, true); PackageNode pkg = getPackageNode(pkgFullName, true);
doPkg(pkg, pkgFullName); processPackageFull(pkg, pkgFullName);
String alias = deobfPresets.getForCls(classInfo); String alias = deobfPresets.getForCls(classInfo);
if (alias != null) { if (alias != null) {
...@@ -372,6 +372,24 @@ public class Deobfuscator { ...@@ -372,6 +372,24 @@ public class Deobfuscator {
return makeClsAlias(cls); return makeClsAlias(cls);
} }
public String getPkgAlias(ClassNode cls) {
ClassInfo classInfo = cls.getClassInfo();
PackageNode pkg = null;
DeobfClsInfo deobfClsInfo = clsMap.get(classInfo);
if (deobfClsInfo != null) {
pkg = deobfClsInfo.getPkg();
} else {
String fullPkgName = classInfo.getPackage();
pkg = getPackageNode(fullPkgName, true);
processPackageFull(pkg, fullPkgName);
}
if (pkg.hasAnyAlias()) {
return pkg.getFullAlias();
} else {
return pkg.getFullName();
}
}
private String makeClsAlias(ClassNode cls) { private String makeClsAlias(ClassNode cls) {
ClassInfo classInfo = cls.getClassInfo(); ClassInfo classInfo = cls.getClassInfo();
String alias = null; String alias = null;
...@@ -472,7 +490,7 @@ public class Deobfuscator { ...@@ -472,7 +490,7 @@ public class Deobfuscator {
return alias; return alias;
} }
private void doPkg(PackageNode pkg, String fullName) { private void processPackageFull(PackageNode pkg, String fullName) {
if (pkgSet.contains(fullName)) { if (pkgSet.contains(fullName)) {
return; return;
} }
...@@ -482,15 +500,19 @@ public class Deobfuscator { ...@@ -482,15 +500,19 @@ public class Deobfuscator {
PackageNode parentPkg = pkg.getParentPackage(); PackageNode parentPkg = pkg.getParentPackage();
while (!parentPkg.getName().isEmpty()) { while (!parentPkg.getName().isEmpty()) {
if (!parentPkg.hasAlias()) { if (!parentPkg.hasAlias()) {
doPkg(parentPkg, parentPkg.getFullName()); processPackageFull(parentPkg, parentPkg.getFullName());
} }
parentPkg = parentPkg.getParentPackage(); parentPkg = parentPkg.getParentPackage();
} }
String pkgName = pkg.getName(); if (!pkg.hasAlias()) {
if (!pkg.hasAlias() && shouldRename(pkgName)) { String pkgName = pkg.getName();
String pkgAlias = String.format("p%03d%s", pkgIndex++, prepareNamePart(pkgName)); if ((args.isDeobfuscationOn() && shouldRename(pkgName))
pkg.setAlias(pkgAlias); || (args.isRenameValid() && !NameMapper.isValidIdentifier(pkgName))
|| (args.isRenamePrintable() && !NameMapper.isAllCharsPrintable(pkgName))) {
String pkgAlias = String.format("p%03d%s", pkgIndex++, prepareNamePart(pkg.getName()));
pkg.setAlias(pkgAlias);
}
} }
} }
......
...@@ -95,25 +95,37 @@ public class RenameVisitor extends AbstractVisitor { ...@@ -95,25 +95,37 @@ public class RenameVisitor extends AbstractVisitor {
classInfo.changeShortName(newShortName); classInfo.changeShortName(newShortName);
cls.addAttr(new RenameReasonAttr(cls).append("invalid class name")); cls.addAttr(new RenameReasonAttr(cls).append("invalid class name"));
} }
if (args.isRenameValid()) { if (classInfo.isInner() && args.isRenameValid()) {
if (classInfo.isInner()) { // check inner classes names
ClassInfo parentClass = classInfo.getParentClass(); ClassInfo parentClass = classInfo.getParentClass();
while (parentClass != null) { while (parentClass != null) {
if (parentClass.getAliasShortName().equals(clsName)) { if (parentClass.getAliasShortName().equals(clsName)) {
String clsAlias = deobfuscator.getClsAlias(cls); String clsAlias = deobfuscator.getClsAlias(cls);
classInfo.changeShortName(clsAlias); classInfo.changeShortName(clsAlias);
cls.addAttr(new RenameReasonAttr(cls).append("collision with other inner class name")); cls.addAttr(new RenameReasonAttr(cls).append("collision with other inner class name"));
break; break;
}
parentClass = parentClass.getParentClass();
}
} else {
if (classInfo.getAliasPkg().isEmpty()) {
classInfo.changePkg(Consts.DEFAULT_PACKAGE_NAME);
cls.addAttr(new RenameReasonAttr(cls).append("default package"));
} }
parentClass = parentClass.getParentClass();
} }
} }
checkPackage(deobfuscator, cls, classInfo, args);
}
private static void checkPackage(Deobfuscator deobfuscator, ClassNode cls, ClassInfo classInfo, JadxArgs args) {
if (classInfo.isInner()) {
return;
}
String aliasPkg = classInfo.getAliasPkg();
if (args.isRenameValid() && aliasPkg.isEmpty()) {
classInfo.changePkg(Consts.DEFAULT_PACKAGE_NAME);
cls.addAttr(new RenameReasonAttr(cls).append("default package"));
return;
}
String fullPkgAlias = deobfuscator.getPkgAlias(cls);
if (!fullPkgAlias.equals(aliasPkg)) {
classInfo.changePkg(fullPkgAlias);
cls.addAttr(new RenameReasonAttr(cls).append("invalid package"));
}
} }
@Nullable @Nullable
......
...@@ -22,7 +22,7 @@ public class CodeGenUtils { ...@@ -22,7 +22,7 @@ public class CodeGenUtils {
code.startLine("/* renamed from: ").add(origName); code.startLine("/* renamed from: ").add(origName);
RenameReasonAttr renameReasonAttr = node.get(AType.RENAME_REASON); RenameReasonAttr renameReasonAttr = node.get(AType.RENAME_REASON);
if (renameReasonAttr != null) { if (renameReasonAttr != null) {
code.add(" reason: "); code.add(" reason: ");
code.add(renameReasonAttr.getDescription()); code.add(renameReasonAttr.getDescription());
} }
code.add(" */"); code.add(" */");
......
package jadx.tests.integration.names;
import java.util.List;
import org.junit.jupiter.api.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.SmaliTest;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.not;
public class TestReservedPackageNames extends SmaliTest {
// @formatter:off
/*
package do.if;
public class A {}
*/
// @formatter:on
@Test
public void test() {
List<ClassNode> clsList = loadFromSmaliFiles();
for (ClassNode cls : clsList) {
String code = cls.getCode().toString();
assertThat(code, not(containsString("package do.if;")));
}
}
@Test
public void testDeobf() {
enableDeobfuscation();
List<ClassNode> clsList = loadFromSmaliFiles();
for (ClassNode cls : clsList) {
String code = cls.getCode().toString();
assertThat(code, not(containsString("package do.if;")));
}
}
@Test
public void testRenameDisabled() {
args.setRenameCaseSensitive(false);
args.setRenameValid(false);
args.setRenamePrintable(false);
disableCompilation();
List<ClassNode> clsList = loadFromSmaliFiles();
for (ClassNode cls : clsList) {
String code = cls.getCode().toString();
if (cls.getShortName().equals("A")) {
assertThat(code, containsString("package do.if;"));
}
}
}
}
.class public Ldo/if/A;
.super Ljava/lang/Object;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment