build exclude list in init method to improve performance, add default values migration
This commit is contained in:
@@ -126,9 +126,9 @@ options:
|
||||
'read-and-autosave-before-closing' - read and autosave before exiting the app or closing the project
|
||||
'ignore' - don't read or save (can be used to skip loading mapping files referenced in the project file)
|
||||
--deobf - activate deobfuscation
|
||||
--deobf-min - min length of name, renamed if shorter, default: 2
|
||||
--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
|
||||
--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)
|
||||
|
||||
@@ -28,6 +28,7 @@ import jadx.api.args.GeneratedRenamesMappingFileMode;
|
||||
import jadx.api.args.IntegerFormat;
|
||||
import jadx.api.args.ResourceNameSource;
|
||||
import jadx.api.args.UserRenamesMappingsMode;
|
||||
import jadx.core.deobf.conditions.DeobfWhitelist;
|
||||
import jadx.core.utils.exceptions.JadxArgsValidateException;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
|
||||
@@ -136,7 +137,7 @@ public class JadxCLIArgs {
|
||||
protected boolean deobfuscationOn = false;
|
||||
|
||||
@Parameter(names = { "--deobf-min" }, description = "min length of name, renamed if shorter")
|
||||
protected int deobfuscationMinLength = 2;
|
||||
protected int deobfuscationMinLength = 3;
|
||||
|
||||
@Parameter(names = { "--deobf-max" }, description = "max length of name, renamed if longer")
|
||||
protected int deobfuscationMaxLength = 64;
|
||||
@@ -145,7 +146,7 @@ public class JadxCLIArgs {
|
||||
names = { "--deobf-whitelist" },
|
||||
description = "space separated list of classes (full name) and packages (ends with '.*') to exclude from deobfuscation"
|
||||
)
|
||||
protected String deobfuscationWhitelistStr = "";
|
||||
protected String deobfuscationWhitelistStr = DeobfWhitelist.DEFAULT_STR;
|
||||
|
||||
@Parameter(
|
||||
names = { "--deobf-cfg-file" },
|
||||
|
||||
@@ -32,6 +32,7 @@ import jadx.api.plugins.loader.JadxPluginLoader;
|
||||
import jadx.api.usage.IUsageInfoCache;
|
||||
import jadx.api.usage.impl.InMemoryUsageInfoCache;
|
||||
import jadx.core.deobf.DeobfAliasProvider;
|
||||
import jadx.core.deobf.conditions.DeobfWhitelist;
|
||||
import jadx.core.deobf.conditions.JadxRenameConditions;
|
||||
import jadx.core.plugins.PluginContext;
|
||||
import jadx.core.utils.files.FileUtils;
|
||||
@@ -109,7 +110,7 @@ public class JadxArgs implements Closeable {
|
||||
/**
|
||||
* List of classes and packages (ends with '.*') to exclude from deobfuscation
|
||||
*/
|
||||
private List<String> deobfuscationWhitelist = new ArrayList<>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,90 @@
|
||||
package jadx.core.deobf.conditions;
|
||||
|
||||
import java.util.Arrays;
|
||||
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.*",
|
||||
"android.os.*",
|
||||
"androidx.core.os.*",
|
||||
"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
|
||||
public Action check(PackageNode pkg) {
|
||||
String pkgName = pkg.getPkgInfo().getFullName();
|
||||
if (packages.stream().anyMatch(pattern -> pattern.equals(pkgName) || pkgName.startsWith(pattern + "."))) {
|
||||
if (packages.contains(pkg.getPkgInfo().getFullName())) {
|
||||
return Action.FORBID_RENAME;
|
||||
}
|
||||
return Action.NO_ACTION;
|
||||
@@ -39,10 +92,10 @@ 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 check(cls.getPackageNode());
|
||||
return Action.NO_ACTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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