Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5640f3b931 | |||
| 02bc27e887 | |||
| 794e5adb7f | |||
| a81cec7701 |
@@ -128,7 +128,7 @@ options:
|
||||
--deobf - activate deobfuscation
|
||||
--deobf-min - min length of name, renamed if shorter, default: 3
|
||||
--deobf-max - max length of name, renamed if longer, default: 64
|
||||
--deobf-whitelist - space separated list of classes (full name) and packages (ends with '.*') to exclude from deobfuscation, default: android.support.v4.* android.support.v7.* android.support.v4.os.* android.support.annotation.Px androidx.core.os.* androidx.annotation.Px
|
||||
--deobf-whitelist - space separated list of classes (full name) and packages (ends with '.*') to exclude from deobfuscation, default: android.support.* android.os.* androidx.core.os.* androidx.annotation.*
|
||||
--deobf-cfg-file - deobfuscation mappings file used for JADX auto-generated names (in the JOBF file format), default: same dir and name as input file with '.jobf' extension
|
||||
--deobf-cfg-file-mode - set mode for handling the JADX auto-generated names' deobfuscation map file:
|
||||
'read' - read if found, don't save (default)
|
||||
|
||||
@@ -110,7 +110,7 @@ public class JadxArgs implements Closeable {
|
||||
/**
|
||||
* List of classes and packages (ends with '.*') to exclude from deobfuscation
|
||||
*/
|
||||
private List<String> deobfuscationWhitelist = DeobfWhitelist.DEFAULT_LIST;
|
||||
private List<String> deobfuscationWhitelist = new ArrayList<>(DeobfWhitelist.DEFAULT_LIST);
|
||||
|
||||
/**
|
||||
* Nodes alias provider for deobfuscator and rename visitor
|
||||
|
||||
@@ -118,7 +118,6 @@ public final class JadxDecompiler implements Closeable {
|
||||
loadInputFiles();
|
||||
|
||||
root = new RootNode(args);
|
||||
root.init();
|
||||
root.setDecompilerRef(this);
|
||||
root.mergePasses(customPasses);
|
||||
root.loadClasses(loadedInputs);
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.slf4j.LoggerFactory;
|
||||
import jadx.api.CommentsLevel;
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.core.deobf.DeobfuscatorVisitor;
|
||||
import jadx.core.deobf.InitRenameProviders;
|
||||
import jadx.core.deobf.SaveDeobfMapping;
|
||||
import jadx.core.dex.attributes.AFlag;
|
||||
import jadx.core.dex.visitors.AnonymousClassVisitor;
|
||||
@@ -102,6 +103,7 @@ public class Jadx {
|
||||
passes.add(new CollectConstValues());
|
||||
|
||||
// rename and deobfuscation
|
||||
passes.add(new InitRenameProviders());
|
||||
passes.add(new DeobfuscatorVisitor());
|
||||
passes.add(new SourceFileRename());
|
||||
passes.add(new RenameVisitor());
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package jadx.core.deobf;
|
||||
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
import jadx.core.dex.visitors.AbstractVisitor;
|
||||
import jadx.core.utils.exceptions.JadxException;
|
||||
|
||||
public class InitRenameProviders extends AbstractVisitor {
|
||||
|
||||
@Override
|
||||
public void init(RootNode root) throws JadxException {
|
||||
JadxArgs args = root.getArgs();
|
||||
if (args.isDeobfuscationOn() || !args.getRenameFlags().isEmpty()) {
|
||||
args.getAliasProvider().init(root);
|
||||
}
|
||||
if (args.isDeobfuscationOn()) {
|
||||
args.getRenameCondition().init(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,39 +5,81 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.core.dex.nodes.PackageNode;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
import jadx.core.utils.Utils;
|
||||
|
||||
public class DeobfWhitelist extends AbstractDeobfCondition {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DeobfWhitelist.class);
|
||||
|
||||
public static final List<String> DEFAULT_LIST = Arrays.asList(
|
||||
"android.support.v4.*",
|
||||
"android.support.v7.*",
|
||||
"android.support.v4.os.*",
|
||||
"android.support.annotation.Px",
|
||||
"android.support.*",
|
||||
"android.os.*",
|
||||
"androidx.core.os.*",
|
||||
"androidx.annotation.Px");
|
||||
"androidx.annotation.*");
|
||||
|
||||
public static final String DEFAULT_STR = Utils.listToString(DEFAULT_LIST, " ");
|
||||
|
||||
private final Set<String> packages = new HashSet<>();
|
||||
private final Set<String> classes = new HashSet<>();
|
||||
private final Set<ClassNode> classes = new HashSet<>();
|
||||
private boolean reportMissingItems = false;
|
||||
|
||||
@Override
|
||||
public void init(RootNode root) {
|
||||
packages.clear();
|
||||
classes.clear();
|
||||
for (String whitelistItem : root.getArgs().getDeobfuscationWhitelist()) {
|
||||
if (!whitelistItem.isEmpty()) {
|
||||
if (whitelistItem.endsWith(".*")) {
|
||||
packages.add(whitelistItem.substring(0, whitelistItem.length() - 2));
|
||||
} else {
|
||||
classes.add(whitelistItem);
|
||||
}
|
||||
List<String> excludeList = root.getArgs().getDeobfuscationWhitelist();
|
||||
reportMissingItems = !excludeList.equals(DEFAULT_LIST);
|
||||
for (String name : excludeList) {
|
||||
if (name.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (name.endsWith(".*")) {
|
||||
excludePackage(root, name.substring(0, name.length() - 2));
|
||||
} else {
|
||||
excludeClass(root, name);
|
||||
}
|
||||
}
|
||||
LOG.debug("Excluded from deobfuscation: {} packages, {} classes", packages.size(), classes.size());
|
||||
}
|
||||
|
||||
private void excludeClass(RootNode root, String clsFullName) {
|
||||
ClassNode cls = root.resolveClass(clsFullName);
|
||||
if (cls == null) {
|
||||
if (reportMissingItems) {
|
||||
LOG.info("Can't exclude from deobfuscation: class '{}' not found", clsFullName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
excludeClsNode(cls);
|
||||
}
|
||||
|
||||
private void excludeClsNode(ClassNode cls) {
|
||||
classes.add(cls);
|
||||
cls.addInfoComment("Class excluded from deobfuscation");
|
||||
}
|
||||
|
||||
private void excludePackage(RootNode root, String fullPkgName) {
|
||||
PackageNode pkg = root.resolvePackage(fullPkgName);
|
||||
if (pkg == null) {
|
||||
if (reportMissingItems) {
|
||||
LOG.info("Can't exclude from deobfuscation: package '{}' not found", fullPkgName);
|
||||
}
|
||||
return;
|
||||
}
|
||||
excludePkgNode(pkg);
|
||||
}
|
||||
|
||||
private void excludePkgNode(PackageNode pkg) {
|
||||
packages.add(pkg.getFullName());
|
||||
pkg.getClasses().forEach(this::excludeClsNode);
|
||||
pkg.getSubPackages().forEach(this::excludePkgNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,9 +92,19 @@ public class DeobfWhitelist extends AbstractDeobfCondition {
|
||||
|
||||
@Override
|
||||
public Action check(ClassNode cls) {
|
||||
if (classes.contains(cls.getClassInfo().getFullName())) {
|
||||
if (classes.contains(cls)) {
|
||||
return Action.FORBID_RENAME;
|
||||
}
|
||||
return Action.NO_ACTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action check(FieldNode fld) {
|
||||
return check(fld.getParentClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action check(MethodNode mth) {
|
||||
return check(mth.getParentClass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,15 +109,6 @@ public class RootNode {
|
||||
this.typeUtils = new TypeUtils(this);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
if (args.isDeobfuscationOn() || !args.getRenameFlags().isEmpty()) {
|
||||
args.getAliasProvider().init(this);
|
||||
}
|
||||
if (args.isDeobfuscationOn()) {
|
||||
args.getRenameCondition().init(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadClasses(List<ICodeLoader> loadedInputs) {
|
||||
for (ICodeLoader codeLoader : loadedInputs) {
|
||||
codeLoader.visitClasses(cls -> {
|
||||
|
||||
+10
@@ -1,9 +1,14 @@
|
||||
package jadx.tests.integration.deobf.a;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.api.deobf.IDeobfCondition;
|
||||
import jadx.api.deobf.impl.CombineDeobfConditions;
|
||||
import jadx.core.deobf.conditions.AvoidClsAndPkgNamesCollision;
|
||||
import jadx.core.deobf.conditions.JadxRenameConditions;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
@@ -34,6 +39,11 @@ public class TestNegativeRenameCondition extends IntegrationTest {
|
||||
// disable all renaming options
|
||||
args.setRenameFlags(Collections.emptySet());
|
||||
|
||||
// disable rename by collision between class and package names
|
||||
List<IDeobfCondition> list = JadxRenameConditions.buildDefaultDeobfConditions();
|
||||
list.removeIf(c -> c.getClass().equals(AvoidClsAndPkgNamesCollision.class));
|
||||
args.setRenameCondition(CombineDeobfConditions.combine(list));
|
||||
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.doesNotContain("renamed from")
|
||||
|
||||
@@ -35,6 +35,7 @@ import jadx.api.args.ResourceNameSource;
|
||||
import jadx.api.args.UserRenamesMappingsMode;
|
||||
import jadx.cli.JadxCLIArgs;
|
||||
import jadx.cli.LogHelper;
|
||||
import jadx.core.deobf.conditions.DeobfWhitelist;
|
||||
import jadx.gui.cache.code.CodeCacheMode;
|
||||
import jadx.gui.cache.usage.UsageCacheMode;
|
||||
import jadx.gui.settings.data.ShortcutsWrapper;
|
||||
@@ -53,7 +54,7 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
|
||||
private static final Path USER_HOME = Paths.get(System.getProperty("user.home"));
|
||||
private static final int RECENT_PROJECTS_COUNT = 30;
|
||||
private static final int CURRENT_SETTINGS_VERSION = 20;
|
||||
private static final int CURRENT_SETTINGS_VERSION = 21;
|
||||
|
||||
private static final Font DEFAULT_FONT = new RSyntaxTextArea().getFont();
|
||||
|
||||
@@ -805,6 +806,10 @@ public class JadxSettings extends JadxCLIArgs {
|
||||
tabDndGhostType = TabDndGhostType.OUTLINE;
|
||||
fromVersion++;
|
||||
}
|
||||
if (fromVersion == 20) {
|
||||
deobfuscationWhitelistStr = DeobfWhitelist.DEFAULT_STR;
|
||||
fromVersion++;
|
||||
}
|
||||
if (fromVersion != CURRENT_SETTINGS_VERSION) {
|
||||
LOG.warn("Incorrect settings upgrade. Expected version: {}, got: {}", CURRENT_SETTINGS_VERSION, fromVersion);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user