From 6f973ca2af23bdfcad45302624c6a083a072addc Mon Sep 17 00:00:00 2001 From: Jan S Date: Wed, 8 May 2019 18:06:49 +0200 Subject: [PATCH] feat(cli): decompile only a single class (PR #657) --- jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java | 6 ++++++ jadx-core/src/main/java/jadx/api/JadxArgs.java | 14 ++++++++++++++ .../src/main/java/jadx/api/JadxDecompiler.java | 5 +++++ 3 files changed, 25 insertions(+) diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java index 4a3a32d43ee..206c3d597f6 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java @@ -43,6 +43,9 @@ public class JadxCLIArgs { @Parameter(names = { "-s", "--no-src" }, description = "do not decompile source code") protected boolean skipSources = false; + @Parameter(names = { "--single-class" }, description = "decompile a single class") + protected String singleClass = null; + @Parameter(names = { "-e", "--export-gradle" }, description = "save as android gradle project") protected boolean exportAsGradleProject = false; @@ -173,6 +176,9 @@ public JadxArgs toJadxArgs() { args.setOutDirRes(FileUtils.toFile(outDirRes)); args.setThreadsCount(threadsCount); args.setSkipSources(skipSources); + if (singleClass != null) { + args.setClassFilter((className) -> singleClass.equals(className)); + } args.setSkipResources(skipResources); args.setFallbackMode(fallbackMode); args.setShowInconsistentCode(showInconsistentCode); diff --git a/jadx-core/src/main/java/jadx/api/JadxArgs.java b/jadx-core/src/main/java/jadx/api/JadxArgs.java index 8610e3c0fd1..6707a72ac63 100644 --- a/jadx-core/src/main/java/jadx/api/JadxArgs.java +++ b/jadx-core/src/main/java/jadx/api/JadxArgs.java @@ -6,6 +6,7 @@ import java.util.EnumSet; import java.util.List; import java.util.Set; +import java.util.function.Predicate; public class JadxArgs { @@ -36,6 +37,11 @@ public class JadxArgs { private boolean skipResources = false; private boolean skipSources = false; + /** + * Predicate that allows to filter the classes to be process based on their full name + */ + private Predicate classFilter = null; + private boolean deobfuscationOn = false; private boolean deobfuscationForceSave = false; private boolean useSourceNameAsClassAlias = false; @@ -182,6 +188,14 @@ public void setSkipSources(boolean skipSources) { this.skipSources = skipSources; } + public Predicate getClassFilter() { + return classFilter; + } + + public void setClassFilter(Predicate classFilter) { + this.classFilter = classFilter; + } + public boolean isDeobfuscationOn() { return deobfuscationOn; } diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index 0b2e72cd253..7391e7adb18 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -13,6 +13,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.function.Predicate; import org.jf.baksmali.Adaptors.ClassDefinition; import org.jf.baksmali.BaksmaliOptions; @@ -203,10 +204,14 @@ private void appendResourcesSave(ExecutorService executor, File outDir) { } private void appendSourcesSave(ExecutorService executor, File outDir) { + final Predicate classFilter = args.getClassFilter(); for (JavaClass cls : getClasses()) { if (cls.getClassNode().contains(AFlag.DONT_GENERATE)) { continue; } + if (classFilter != null && !classFilter.test(cls.getFullName())) { + continue; + } executor.execute(() -> { try { cls.decompile();