feat: plugin options, add verify checksum option for dex input (#1385)

This commit is contained in:
Skylot
2022-02-21 19:13:03 +00:00
parent 09335395f5
commit 54683e3198
24 changed files with 435 additions and 25 deletions
@@ -17,6 +17,11 @@ import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameterized;
import jadx.api.JadxDecompiler;
import jadx.api.plugins.JadxPlugin;
import jadx.api.plugins.JadxPluginInfo;
import jadx.api.plugins.JadxPluginManager;
import jadx.api.plugins.options.JadxPluginOptions;
import jadx.api.plugins.options.OptionDescription;
public class JCommanderWrapper<T> {
private final JCommander jc;
@@ -70,24 +75,25 @@ public class JCommanderWrapper<T> {
maxNamesLen = len;
}
}
maxNamesLen += 3;
JadxCLIArgs args = (JadxCLIArgs) jc.getObjects().get(0);
for (Field f : getFields(args.getClass())) {
String name = f.getName();
ParameterDescription p = paramsMap.get(name);
if (p == null) {
if (p == null || p.getParameter().hidden()) {
continue;
}
StringBuilder opt = new StringBuilder();
opt.append(" ").append(p.getNames());
String description = p.getDescription();
addSpaces(opt, maxNamesLen - opt.length() + 3);
addSpaces(opt, maxNamesLen - opt.length());
if (description.contains("\n")) {
String[] lines = description.split("\n");
opt.append("- ").append(lines[0]);
for (int i = 1; i < lines.length; i++) {
opt.append('\n');
addSpaces(opt, maxNamesLen + 5);
addSpaces(opt, maxNamesLen + 2);
opt.append(lines[i]);
}
} else {
@@ -99,11 +105,14 @@ public class JCommanderWrapper<T> {
}
out.println(opt);
}
out.println(appendPluginOptions(maxNamesLen));
out.println();
out.println("Examples:");
out.println(" jadx -d out classes.dex");
out.println(" jadx --rename-flags \"none\" classes.dex");
out.println(" jadx --rename-flags \"valid, printable\" classes.dex");
out.println(" jadx --log-level ERROR app.apk");
out.println(" jadx -Pdex-input.verify-checksum=no app.apk");
}
/**
@@ -145,4 +154,46 @@ public class JCommanderWrapper<T> {
str.append(' ');
}
}
private String appendPluginOptions(int maxNamesLen) {
StringBuilder sb = new StringBuilder();
JadxPluginManager pluginManager = new JadxPluginManager();
pluginManager.load();
int k = 1;
for (JadxPlugin plugin : pluginManager.getAllPlugins()) {
if (plugin instanceof JadxPluginOptions) {
if (appendPlugin(((JadxPluginOptions) plugin), sb, maxNamesLen, k)) {
k++;
}
}
}
if (sb.length() == 0) {
return "";
}
return "\nPlugin options (-P<name>=<value>):" + sb;
}
private boolean appendPlugin(JadxPluginOptions plugin, StringBuilder out, int maxNamesLen, int k) {
List<OptionDescription> descs = plugin.getOptionsDescriptions();
if (descs.isEmpty()) {
return false;
}
JadxPluginInfo pluginInfo = plugin.getPluginInfo();
out.append("\n ").append(k).append(") ");
out.append(pluginInfo.getPluginId()).append(" (").append(pluginInfo.getDescription()).append(") ");
for (OptionDescription desc : descs) {
StringBuilder opt = new StringBuilder();
opt.append(" -P").append(desc.name());
addSpaces(opt, maxNamesLen - opt.length());
opt.append("- ").append(desc.description());
if (!desc.values().isEmpty()) {
opt.append(", values: ").append(desc.values());
}
if (desc.defaultValue() != null) {
opt.append(", default: ").append(desc.defaultValue());
}
out.append("\n").append(opt);
}
return true;
}
}
+34 -2
View File
@@ -7,6 +7,7 @@ import jadx.api.JadxArgs;
import jadx.api.JadxDecompiler;
import jadx.api.impl.NoOpCodeCache;
import jadx.api.impl.SimpleCodeWriter;
import jadx.cli.LogHelper.LogLevelEnum;
import jadx.core.utils.exceptions.JadxArgsValidateException;
import jadx.core.utils.files.FileUtils;
@@ -21,7 +22,7 @@ public class JadxCLI {
LOG.error("Incorrect arguments: {}", e.getMessage());
result = 1;
} catch (Exception e) {
LOG.error("jadx error: {}", e.getMessage(), e);
LOG.error("Process error:", e);
result = 1;
} finally {
FileUtils.deleteTempRootDir();
@@ -38,11 +39,16 @@ public class JadxCLI {
}
private static int processAndSave(JadxCLIArgs cliArgs) {
setLogLevelsForLoadingStage(cliArgs);
JadxArgs jadxArgs = cliArgs.toJadxArgs();
jadxArgs.setCodeCache(new NoOpCodeCache());
jadxArgs.setCodeWriterProvider(SimpleCodeWriter::new);
try (JadxDecompiler jadx = new JadxDecompiler(jadxArgs)) {
jadx.load();
if (checkForErrors(jadx)) {
return 1;
}
LogHelper.setLogLevelFromArgs(cliArgs);
if (!SingleClassMode.process(jadx, cliArgs)) {
save(jadx);
}
@@ -57,8 +63,34 @@ public class JadxCLI {
return 0;
}
private static void setLogLevelsForLoadingStage(JadxCLIArgs cliArgs) {
switch (cliArgs.getLogLevel()) {
case QUIET:
LogHelper.setLogLevelFromArgs(cliArgs);
break;
case PROGRESS:
// show load errors
LogHelper.applyLogLevel(LogLevelEnum.ERROR);
break;
}
}
private static boolean checkForErrors(JadxDecompiler jadx) {
if (jadx.getRoot().getClasses().isEmpty()) {
LOG.error("Load failed! No classes for decompile!");
return true;
}
if (jadx.getErrorsCount() > 0) {
LOG.error("Load with errors! Check log for details");
// continue processing
return false;
}
return false;
}
private static void save(JadxDecompiler jadx) {
if (LogHelper.getLogLevel() == LogHelper.LogLevelEnum.QUIET) {
if (LogHelper.getLogLevel() == LogLevelEnum.QUIET) {
jadx.save();
} else {
jadx.save(500, (done, total) -> {
@@ -2,12 +2,15 @@ package jadx.cli;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.beust.jcommander.DynamicParameter;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.Parameter;
@@ -177,6 +180,9 @@ public class JadxCLIArgs {
@Parameter(names = { "-h", "--help" }, description = "print this help", help = true)
protected boolean printHelp = false;
@DynamicParameter(names = "-P", description = "Plugin options", hidden = true)
protected Map<String, String> pluginOptions = new HashMap<>();
public boolean processArgs(String[] args) {
JCommanderWrapper<JadxCLIArgs> jcw = new JCommanderWrapper<>(this);
return jcw.parse(args) && process(jcw);
@@ -212,7 +218,6 @@ public class JadxCLIArgs {
if (threadsCount <= 0) {
throw new JadxException("Threads count must be positive, got: " + threadsCount);
}
LogHelper.setLogLevelFromArgs(this);
} catch (JadxException e) {
System.err.println("ERROR: " + e.getMessage());
jcw.printUsage();
@@ -260,6 +265,7 @@ public class JadxCLIArgs {
args.setFsCaseSensitive(fsCaseSensitive);
args.setCommentsLevel(commentsLevel);
args.setUseDxInput(useDx);
args.setPluginOptions(pluginOptions);
return args;
}
@@ -411,6 +417,14 @@ public class JadxCLIArgs {
return commentsLevel;
}
public LogHelper.LogLevelEnum getLogLevel() {
return logLevel;
}
public Map<String, String> getPluginOptions() {
return pluginOptions;
}
static class RenameConverter implements IStringConverter<Set<RenameEnum>> {
private final String paramName;