Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement a whitelist for deobfuscation #2040

Merged
merged 1 commit into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ 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
9 changes: 9 additions & 0 deletions jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ 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-cfg-file" },
description = "deobfuscation mappings file used for JADX auto-generated names (in the JOBF file format),"
Expand Down Expand Up @@ -316,6 +320,7 @@ public JadxArgs toJadxArgs() {
args.setGeneratedRenamesMappingFileMode(generatedRenamesMappingFileMode);
args.setDeobfuscationMinLength(deobfuscationMinLength);
args.setDeobfuscationMaxLength(deobfuscationMaxLength);
args.setDeobfuscationWhitelist(deobfuscationWhitelist);
args.setUseSourceNameAsClassAlias(deobfuscationUseSourceNameAsAlias);
args.setUseKotlinMethodsForVarNames(useKotlinMethodsForVarNames);
args.setResourceNameSource(resourceNameSource);
Expand Down Expand Up @@ -443,6 +448,10 @@ public int getDeobfuscationMaxLength() {
return deobfuscationMaxLength;
}

public String getDeobfuscationWhitelist() {
return deobfuscationWhitelist;
}

public String getGeneratedRenamesMappingFile() {
return generatedRenamesMappingFile;
}
Expand Down
11 changes: 11 additions & 0 deletions jadx-core/src/main/java/jadx/api/JadxArgs.java
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ public class JadxArgs implements Closeable {
private int deobfuscationMinLength = 0;
private int deobfuscationMaxLength = Integer.MAX_VALUE;

private String deobfuscationWhitelist = "";

/**
* Nodes alias provider for deobfuscator and rename visitor
*/
Expand Down Expand Up @@ -434,6 +436,14 @@ public void setDeobfuscationMaxLength(int deobfuscationMaxLength) {
this.deobfuscationMaxLength = deobfuscationMaxLength;
}

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

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

public File getGeneratedRenamesMappingFile() {
return generatedRenamesMappingFile;
}
Expand Down Expand Up @@ -714,6 +724,7 @@ public String toString() {
+ ", extractFinally=" + extractFinally
+ ", deobfuscationMinLength=" + deobfuscationMinLength
+ ", deobfuscationMaxLength=" + deobfuscationMaxLength
+ ", deobfuscationWhitelist=" + deobfuscationWhitelist
+ ", escapeUnicode=" + escapeUnicode
+ ", replaceConsts=" + replaceConsts
+ ", respectBytecodeAccModifiers=" + respectBytecodeAccModifiers
Expand Down
78 changes: 78 additions & 0 deletions jadx-core/src/main/java/jadx/core/deobf/DeobfWhitelist.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package jadx.core.deobf;

import java.util.ArrayList;
import java.util.List;

import jadx.api.JadxArgs;
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 DeobfWhitelist implements IRenameCondition {

private static DeobfWhitelist whitelist = null;

private final List<String> packages = new ArrayList<>();

private final List<String> classes = new ArrayList<>();

public static DeobfWhitelist getWhitelist() {
if (whitelist == null) {
whitelist = new DeobfWhitelist();
}
return whitelist;
}

@Override
public void init(RootNode root) {
packages.clear();
classes.clear();
JadxArgs args = root.getArgs();
String whitelistStr = args.getDeobfuscationWhitelist();
String[] whitelisteItems = whitelistStr.split(":");
for (String whitelistItem : whitelisteItems) {
if (!whitelistItem.isEmpty()) {
if (whitelistItem.endsWith(".*")) {
packages.add(whitelistItem.substring(0, whitelistItem.length() - 2));
} else {
classes.add(whitelistItem);
}
}
}
}

@Override
public boolean shouldRename(PackageNode pkg) {
String fullname = pkg.getPkgInfo().getFullName();
for (String p : packages) {
if (fullname.equals(p)) {
return false;
}
}
return true;
}

@Override
public boolean shouldRename(ClassNode cls) {
String fullname = cls.getFullName();
for (String c : classes) {
if (fullname.equals(c)) {
return false;
}
}
return true;
}

@Override
public boolean shouldRename(FieldNode fld) {
return true;
}

@Override
public boolean shouldRename(MethodNode mth) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public void init(RootNode root) throws JadxException {
if (!args.isDeobfuscationOn()) {
return;
}
DeobfWhitelist whitelist = DeobfWhitelist.getWhitelist();
whitelist.init(root);
DeobfPresets mapping = DeobfPresets.build(root);
if (args.getGeneratedRenamesMappingFileMode().shouldRead()) {
if (mapping.load()) {
Expand All @@ -32,9 +34,11 @@ public void init(RootNode root) throws JadxException {
}

public static void process(RootNode root, IRenameCondition renameCondition, IAliasProvider aliasProvider) {
DeobfWhitelist whitelist = DeobfWhitelist.getWhitelist();

boolean pkgUpdated = false;
for (PackageNode pkg : root.getPackages()) {
if (renameCondition.shouldRename(pkg)) {
if (whitelist.shouldRename(pkg) && renameCondition.shouldRename(pkg)) {
String alias = aliasProvider.forPackage(pkg);
if (alias != null) {
pkg.rename(alias, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,12 +236,29 @@ private SettingsGroup makeDeobfuscationGroup() {
}
});

JButton editWhitelistedEntities = new JButton(NLS.str("preferences.excludedPackages.button"));
editWhitelistedEntities.addActionListener(event -> {

String oldEWhitelistedEntities = settings.getDeobfuscationWhitelist();
String result = JOptionPane.showInputDialog(this, NLS.str("preferences.deobfuscation_whitelist.editDialog"),
settings.getDeobfuscationWhitelist());
if (result != null) {
settings.setExcludedPackages(result);
if (!oldEWhitelistedEntities.equals(result)) {
needReload();
}
}
});

SettingsGroup deobfGroup = new SettingsGroup(NLS.str("preferences.deobfuscation"));
deobfGroup.addRow(NLS.str("preferences.deobfuscation_on"), deobfOn);
deobfGroup.addRow(NLS.str("preferences.deobfuscation_min_len"), minLenSpinner);
deobfGroup.addRow(NLS.str("preferences.deobfuscation_max_len"), maxLenSpinner);
deobfGroup.addRow(NLS.str("preferences.deobfuscation_res_name_source"), resNamesSource);
deobfGroup.addRow(NLS.str("preferences.generated_renames_mapping_file_mode"), generatedRenamesMappingFileModeCB);
deobfGroup.addRow(NLS.str("preferences.deobfuscation_whitelist"),
NLS.str("preferences.deobfuscation_whitelist.tooltip"), editWhitelistedEntities);

deobfGroup.end();

Collection<JComponent> connectedComponents = Arrays.asList(minLenSpinner, maxLenSpinner);
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_de_DE.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=Minimale Namenlänge
preferences.deobfuscation_max_len=Maximale Namenlänge
preferences.deobfuscation_source_alias=Quelldateiname als Klassennamen-Alias verwenden
#preferences.deobfuscation_res_name_source=Better resources name source
preferences.deobfuscation_whitelist=Pakete und Klassen von Deobfuskierung ausschließen
preferences.deobfuscation_whitelist.editDialog=Whitelist für Deobfuskierung
preferences.deobfuscation_whitelist.tooltip=Liste der durch ':' getrennten Pakete (Suffix '.*') und Klassenamen, die nicht deobfuskiert werden sollen
preferences.save=Speichern
preferences.cancel=Abbrechen
preferences.reset=Zurücksetzen
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_en_US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=Minimum name length
preferences.deobfuscation_max_len=Maximum name length
preferences.deobfuscation_source_alias=Use source file name as class name alias
preferences.deobfuscation_res_name_source=Better resources name source
preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=Save
preferences.cancel=Cancel
preferences.reset=Reset
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_es_ES.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=Longitud mínima del nombre
preferences.deobfuscation_max_len=Longitud máxima del nombre
preferences.deobfuscation_source_alias=Usar el nombre del source como alias para la clase
#preferences.deobfuscation_res_name_source=Better resources name source
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=Guardar
preferences.cancel=Cancelar
preferences.reset=Reestablecer
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_id_ID.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=Panjang nama minimum
preferences.deobfuscation_max_len=Panjang nama maksimum
preferences.deobfuscation_source_alias=Gunakan nama berkas sumber sebagai alias nama kelas
preferences.deobfuscation_res_name_source=Sumber nama sumber daya yang lebih baik
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=Simpan
preferences.cancel=Batal
preferences.reset=Reset
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_ko_KR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=최소 이름 길이
preferences.deobfuscation_max_len=최대 이름 길이
preferences.deobfuscation_source_alias=소스 파일 이름을 클래스 이름 별칭으로 사용
preferences.deobfuscation_res_name_source=더 나은 리소스 이름 소스
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=저장
preferences.cancel=취소
preferences.reset=재설정
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_pt_BR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=Tamanho mínimo do nome
preferences.deobfuscation_max_len=Tamanho máximo do nome
preferences.deobfuscation_source_alias=Utilizar nome do arquivo como apelido da classe
preferences.deobfuscation_res_name_source=Melhora nome da fonte dos recursos
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=Salvar
preferences.cancel=Cancelar
preferences.reset=Redefinir
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_ru_RU.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=Минимальная длина имени
preferences.deobfuscation_max_len=Максимальная длина имени
preferences.deobfuscation_source_alias=Иcпользовать атрибут SOURCE
preferences.deobfuscation_res_name_source=Расшифровка имен ресурсов
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=Сохранить
preferences.cancel=Отмена
preferences.reset=Сброс
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=最小命名长度
preferences.deobfuscation_max_len=最大命名长度
preferences.deobfuscation_source_alias=使用资源名作为类的别名
preferences.deobfuscation_res_name_source=更好的资源名称来源
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=保存
preferences.cancel=取消
preferences.reset=重置
Expand Down
3 changes: 3 additions & 0 deletions jadx-gui/src/main/resources/i18n/Messages_zh_TW.properties
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ preferences.deobfuscation_min_len=最小名稱長度
preferences.deobfuscation_max_len=最大名稱長度
preferences.deobfuscation_source_alias=將原始檔案名稱作為類別別名
preferences.deobfuscation_res_name_source=較佳的資源名稱來源
#preferences.deobfuscation_whitelist=Exclude packages and classes from deobfuscation
#preferences.deobfuscation_whitelist.editDialog=Whitelist for deobfuscation
#preferences.deobfuscation_whitelist.tooltip=List of ':' separated packages (suffix '.*') and class names that will not be deobfuscated
preferences.save=儲存
preferences.cancel=取消
preferences.reset=重設
Expand Down