Skip to content

Commit

Permalink
refactor(deobf): split deobfuscation conditions (#2040)
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Nov 5, 2023
1 parent f7002c7 commit a989fa7
Show file tree
Hide file tree
Showing 22 changed files with 482 additions and 246 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,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-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)
Expand All @@ -131,7 +132,6 @@ options:
'auto' - automatically select best name (default)
'resources' - use resources names
'code' - use R class fields names
--deobf-whitelist - list of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
--use-kotlin-methods-for-var-names - use kotlin intrinsic methods to rename variables, values: disable, apply, apply-and-hide, default: apply
--rename-flags - fix options (comma-separated list of):
'case' - fix case sensitivity issues (according to --fs-case-sensitive option),
Expand Down
16 changes: 10 additions & 6 deletions jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
Expand All @@ -27,6 +28,7 @@
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.JadxException;
import jadx.core.utils.files.FileUtils;

Expand Down Expand Up @@ -137,9 +139,11 @@ public class JadxCLIArgs {
@Parameter(names = { "--deobf-max" }, description = "max length of name, renamed if longer")
protected int deobfuscationMaxLength = 64;

@Parameter(names = { "--deobf-whitelist}" }, description = "debfucation whitelist")
protected String deobfuscationWhitelist =
"android.support.v4.*:android.support.v7.*:android.support.v4.os.*:android.support.annotation.Px:androidx.core.os.*:androidx.annotation.Px";
@Parameter(
names = { "--deobf-whitelist" },
description = "space separated list of classes (full name) and packages (ends with '.*') to exclude from deobfuscation"
)
protected String deobfuscationWhitelistStr = DeobfWhitelist.DEFAULT_STR;

@Parameter(
names = { "--deobf-cfg-file" },
Expand Down Expand Up @@ -320,7 +324,7 @@ public JadxArgs toJadxArgs() {
args.setGeneratedRenamesMappingFileMode(generatedRenamesMappingFileMode);
args.setDeobfuscationMinLength(deobfuscationMinLength);
args.setDeobfuscationMaxLength(deobfuscationMaxLength);
args.setDeobfuscationWhitelist(deobfuscationWhitelist);
args.setDeobfuscationWhitelist(Arrays.asList(deobfuscationWhitelistStr.split(" ")));
args.setUseSourceNameAsClassAlias(deobfuscationUseSourceNameAsAlias);
args.setUseKotlinMethodsForVarNames(useKotlinMethodsForVarNames);
args.setResourceNameSource(resourceNameSource);
Expand Down Expand Up @@ -448,8 +452,8 @@ public int getDeobfuscationMaxLength() {
return deobfuscationMaxLength;
}

public String getDeobfuscationWhitelist() {
return deobfuscationWhitelist;
public String getDeobfuscationWhitelistStr() {
return deobfuscationWhitelistStr;
}

public String getGeneratedRenamesMappingFile() {
Expand Down
16 changes: 10 additions & 6 deletions jadx-core/src/main/java/jadx/api/JadxArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
import jadx.api.usage.IUsageInfoCache;
import jadx.api.usage.impl.InMemoryUsageInfoCache;
import jadx.core.deobf.DeobfAliasProvider;
import jadx.core.deobf.DeobfCondition;
import jadx.core.deobf.conditions.DeobfWhitelist;
import jadx.core.deobf.conditions.JadxRenameConditions;
import jadx.core.plugins.PluginContext;
import jadx.core.utils.files.FileUtils;

Expand Down Expand Up @@ -103,7 +104,10 @@ public class JadxArgs implements Closeable {
private int deobfuscationMinLength = 0;
private int deobfuscationMaxLength = Integer.MAX_VALUE;

private String deobfuscationWhitelist = "";
/**
* List of classes and packages (ends with '.*') to exclude from deobfuscation
*/
private List<String> deobfuscationWhitelist = DeobfWhitelist.DEFAULT_LIST;

/**
* Nodes alias provider for deobfuscator and rename visitor
Expand All @@ -113,7 +117,7 @@ public class JadxArgs implements Closeable {
/**
* Condition to rename node in deobfuscator
*/
private IRenameCondition renameCondition = new DeobfCondition();
private IRenameCondition renameCondition = JadxRenameConditions.buildDefault();

private boolean escapeUnicode = false;
private boolean replaceConsts = true;
Expand Down Expand Up @@ -436,11 +440,11 @@ public void setDeobfuscationMaxLength(int deobfuscationMaxLength) {
this.deobfuscationMaxLength = deobfuscationMaxLength;
}

public String getDeobfuscationWhitelist() {
public List<String> getDeobfuscationWhitelist() {
return this.deobfuscationWhitelist;
}

public void setDeobfuscationWhitelist(String deobfuscationWhitelist) {
public void setDeobfuscationWhitelist(List<String> deobfuscationWhitelist) {
this.deobfuscationWhitelist = deobfuscationWhitelist;
}

Expand Down Expand Up @@ -678,7 +682,7 @@ public void setLoadJadxClsSetFile(boolean loadJadxClsSetFile) {
public String makeCodeArgsHash(@Nullable JadxDecompiler decompiler) {
String argStr = "args:" + decompilationMode + useImports + showInconsistentCode
+ inlineAnonymousClasses + inlineMethods + moveInnerClasses + allowInlineKotlinLambda
+ deobfuscationOn + deobfuscationMinLength + deobfuscationMaxLength
+ deobfuscationOn + deobfuscationMinLength + deobfuscationMaxLength + deobfuscationWhitelist
+ resourceNameSource
+ useKotlinMethodsForVarNames
+ insertDebugLines + extractFinally
Expand Down
31 changes: 31 additions & 0 deletions jadx-core/src/main/java/jadx/api/deobf/IDeobfCondition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package jadx.api.deobf;

import jadx.api.deobf.impl.CombineDeobfConditions;
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;

/**
* Utility interface to simplify merging several rename conditions to build {@link IRenameCondition}
* instance with {@link CombineDeobfConditions#combine(IDeobfCondition...)}.
*/
public interface IDeobfCondition {

enum Action {
NO_ACTION,
FORCE_RENAME,
FORBID_RENAME,
}

void init(RootNode root);

Action check(PackageNode pkg);

Action check(ClassNode cls);

Action check(FieldNode fld);

Action check(MethodNode mth);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package jadx.api.deobf.impl;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import jadx.api.deobf.IDeobfCondition;
import jadx.api.deobf.IRenameCondition;
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;

public class CombineDeobfConditions implements IRenameCondition {

public static IRenameCondition combine(List<IDeobfCondition> conditions) {
return new CombineDeobfConditions(conditions);
}

public static IRenameCondition combine(IDeobfCondition... conditions) {
return new CombineDeobfConditions(Arrays.asList(conditions));
}

private final List<IDeobfCondition> conditions;

private CombineDeobfConditions(List<IDeobfCondition> conditions) {
if (conditions == null || conditions.isEmpty()) {
throw new IllegalArgumentException("Conditions list can't be empty");
}
this.conditions = conditions;
}

private boolean combineFunc(Function<IDeobfCondition, IDeobfCondition.Action> check) {
for (IDeobfCondition c : conditions) {
switch (check.apply(c)) {
case NO_ACTION:
// ignore
break;
case FORCE_RENAME:
return true;
case FORBID_RENAME:
return false;
}
}
return false;
}

@Override
public void init(RootNode root) {
conditions.forEach(c -> c.init(root));
}

@Override
public boolean shouldRename(PackageNode pkg) {
return combineFunc(c -> c.check(pkg));
}

@Override
public boolean shouldRename(ClassNode cls) {
return combineFunc(c -> c.check(cls));
}

@Override
public boolean shouldRename(FieldNode fld) {
return combineFunc(c -> c.check(fld));
}

@Override
public boolean shouldRename(MethodNode mth) {
return combineFunc(c -> c.check(mth));
}
}
103 changes: 0 additions & 103 deletions jadx-core/src/main/java/jadx/core/deobf/DeobfCondition.java

This file was deleted.

0 comments on commit a989fa7

Please sign in to comment.