提交 8446d016 编写于 作者: S Skylot

cli: update jcommander lib

上级 ab040d36
......@@ -5,7 +5,7 @@ applicationName = 'jadx'
dependencies {
compile(project(':jadx-core'))
compile 'com.beust:jcommander:1.47'
compile 'com.beust:jcommander:1.72'
compile 'ch.qos.logback:logback-classic:1.2.3'
}
......
......@@ -4,6 +4,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.JadxDecompiler;
import jadx.core.utils.exceptions.JadxArgsValidateException;
public class JadxCLI {
private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class);
......@@ -22,7 +23,12 @@ public class JadxCLI {
static void processAndSave(JadxCLIArgs inputArgs) {
JadxDecompiler jadx = new JadxDecompiler(inputArgs.toJadxArgs());
jadx.load();
try {
jadx.load();
} catch (JadxArgsValidateException e) {
LOG.error("Incorrect arguments: {}", e.getMessage());
System.exit(1);
}
jadx.save();
if (jadx.getErrorsCount() != 0) {
jadx.printErrorsReport();
......
......@@ -10,7 +10,6 @@ import java.util.stream.Collectors;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import com.beust.jcommander.IStringConverter;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterDescription;
......@@ -25,7 +24,7 @@ import jadx.core.utils.files.FileUtils;
public class JadxCLIArgs {
@Parameter(description = "<input file> (.dex, .apk, .jar or .class)")
@Parameter(description = "<input file> (.apk, .dex, .jar or .class)")
protected List<String> files = new ArrayList<>(1);
@Parameter(names = {"-d", "--output-dir"}, description = "output directory")
......@@ -37,9 +36,6 @@ public class JadxCLIArgs {
@Parameter(names = {"-dr", "--output-dir-res"}, description = "output directory for resources")
protected String outDirRes;
@Parameter(names = {"-j", "--threads-count"}, description = "processing threads count")
protected int threadsCount = JadxArgs.DEFAULT_THREADS_COUNT;
@Parameter(names = {"-r", "--no-res"}, description = "do not decode resources")
protected boolean skipResources = false;
......@@ -49,15 +45,16 @@ public class JadxCLIArgs {
@Parameter(names = {"-e", "--export-gradle"}, description = "save as android gradle project")
protected boolean exportAsGradleProject = false;
@Parameter(names = {"-j", "--threads-count"}, description = "processing threads count")
protected int threadsCount = JadxArgs.DEFAULT_THREADS_COUNT;
@Parameter(names = {"--show-bad-code"}, description = "show inconsistent code (incorrectly decompiled)")
protected boolean showInconsistentCode = false;
@Parameter(names = {"--no-imports"}, converter = InvertedBooleanConverter.class,
description = "disable use of imports, always write entire package name")
@Parameter(names = {"--no-imports"}, description = "disable use of imports, always write entire package name")
protected boolean useImports = true;
@Parameter(names = "--no-replace-consts", converter = InvertedBooleanConverter.class,
description = "don't replace constant value with matching constant field")
@Parameter(names = "--no-replace-consts", description = "don't replace constant value with matching constant field")
protected boolean replaceConsts = true;
@Parameter(names = {"--escape-unicode"}, description = "escape non latin characters in strings (with \\u)")
......@@ -90,6 +87,9 @@ public class JadxCLIArgs {
@Parameter(names = {"-v", "--verbose"}, description = "verbose output")
protected boolean verbose = false;
@Parameter(names = {"--version"}, description = "print jadx version")
protected boolean printVersion = false;
@Parameter(names = {"-h", "--help"}, description = "print this help", help = true)
protected boolean printHelp = false;
......@@ -99,7 +99,7 @@ public class JadxCLIArgs {
private boolean parse(String[] args) {
try {
new JCommander(this, args);
makeJCommander().parse(args);
return true;
} catch (ParameterException e) {
System.err.println("Arguments parse error: " + e.getMessage());
......@@ -108,16 +108,24 @@ public class JadxCLIArgs {
}
}
private JCommander makeJCommander() {
return JCommander.newBuilder().addObject(this).build();
}
private boolean process() {
if (isPrintHelp()) {
if (printHelp) {
printUsage();
return false;
}
if (printVersion) {
System.out.println(JadxDecompiler.getVersion());
return false;
}
try {
if (threadsCount <= 0) {
throw new JadxException("Threads count must be positive, got: " + threadsCount);
}
if (isVerbose()) {
if (verbose) {
ch.qos.logback.classic.Logger rootLogger =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
// remove INFO ThresholdFilter
......@@ -135,7 +143,7 @@ public class JadxCLIArgs {
}
public void printUsage() {
JCommander jc = new JCommander(this);
JCommander jc = makeJCommander();
// print usage in not sorted fields order (by default its sorted by description)
PrintStream out = System.out;
out.println();
......@@ -162,13 +170,13 @@ public class JadxCLIArgs {
continue;
}
StringBuilder opt = new StringBuilder();
opt.append(' ').append(p.getNames());
opt.append(" ").append(p.getNames());
addSpaces(opt, maxNamesLen - opt.length() + 2);
opt.append("- ").append(p.getDescription());
out.println(opt);
}
out.println("Example:");
out.println(" jadx -d out classes.dex");
out.println(" jadx -d out classes.dex");
}
private static void addSpaces(StringBuilder str, int count) {
......@@ -202,13 +210,6 @@ public class JadxCLIArgs {
return args;
}
public static class InvertedBooleanConverter implements IStringConverter<Boolean> {
@Override
public Boolean convert(String value) {
return "false".equals(value);
}
}
public List<String> getFiles() {
return files;
}
......@@ -225,10 +226,6 @@ public class JadxCLIArgs {
return outDirRes;
}
public boolean isPrintHelp() {
return printHelp;
}
public boolean isSkipResources() {
return skipResources;
}
......@@ -241,14 +238,6 @@ public class JadxCLIArgs {
return threadsCount;
}
public boolean isCFGOutput() {
return cfgOutput;
}
public boolean isRawCFGOutput() {
return rawCfgOutput;
}
public boolean isFallbackMode() {
return fallbackMode;
}
......@@ -261,10 +250,6 @@ public class JadxCLIArgs {
return useImports;
}
public boolean isVerbose() {
return verbose;
}
public boolean isDeobfuscationOn() {
return deobfuscationOn;
}
......@@ -289,6 +274,18 @@ public class JadxCLIArgs {
return escapeUnicode;
}
public boolean isEscapeUnicode() {
return escapeUnicode;
}
public boolean isCfgOutput() {
return cfgOutput;
}
public boolean isRawCfgOutput() {
return rawCfgOutput;
}
public boolean isReplaceConsts() {
return replaceConsts;
}
......
......@@ -5,7 +5,7 @@
<level>INFO</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss} %-5level - %msg%n</pattern>
<pattern>%-5level - %msg%n</pattern>
</encoder>
</appender>
......
package jadx.cli;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
public class JadxCLIArgsTest {
private static final Logger LOG = LoggerFactory.getLogger(JadxCLIArgsTest.class);
@Test
public void testInvertedBooleanOption() {
assertThat(parse("--no-replace-consts").isReplaceConsts(), is(false));
assertThat(parse("").isReplaceConsts(), is(true));
}
@Test
public void testEscapeUnicodeOption() {
assertThat(parse("--escape-unicode").isEscapeUnicode(), is(true));
assertThat(parse("").isEscapeUnicode(), is(false));
}
@Test
public void testSrcOption() {
assertThat(parse("--no-src").isSkipSources(), is(true));
assertThat(parse("-s").isSkipSources(), is(true));
assertThat(parse("").isSkipSources(), is(false));
}
private JadxCLIArgs parse(String... args) {
JadxCLIArgs jadxArgs = new JadxCLIArgs();
boolean res = jadxArgs.processArgs(args);
assertThat(res, is(true));
LOG.info("Jadx args: {}", jadxArgs.toJadxArgs());
return jadxArgs;
}
}
......@@ -211,4 +211,31 @@ public class JadxArgs {
public void setExportAsGradleProject(boolean exportAsGradleProject) {
this.exportAsGradleProject = exportAsGradleProject;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("JadxArgs{");
sb.append("inputFiles=").append(inputFiles);
sb.append(", outDir=").append(outDir);
sb.append(", outDirSrc=").append(outDirSrc);
sb.append(", outDirRes=").append(outDirRes);
sb.append(", threadsCount=").append(threadsCount);
sb.append(", cfgOutput=").append(cfgOutput);
sb.append(", rawCFGOutput=").append(rawCFGOutput);
sb.append(", fallbackMode=").append(fallbackMode);
sb.append(", showInconsistentCode=").append(showInconsistentCode);
sb.append(", useImports=").append(useImports);
sb.append(", isSkipResources=").append(isSkipResources);
sb.append(", isSkipSources=").append(isSkipSources);
sb.append(", isDeobfuscationOn=").append(isDeobfuscationOn);
sb.append(", isDeobfuscationForceSave=").append(isDeobfuscationForceSave);
sb.append(", useSourceNameAsClassAlias=").append(useSourceNameAsClassAlias);
sb.append(", deobfuscationMinLength=").append(deobfuscationMinLength);
sb.append(", deobfuscationMaxLength=").append(deobfuscationMaxLength);
sb.append(", escapeUnicode=").append(escapeUnicode);
sb.append(", replaceConsts=").append(replaceConsts);
sb.append(", exportAsGradleProject=").append(exportAsGradleProject);
sb.append('}');
return sb.toString();
}
}
package jadx.api;
import java.io.File;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.core.utils.exceptions.JadxRuntimeException;
import jadx.core.utils.exceptions.JadxArgsValidateException;
public class JadxArgsValidator {
private static final Logger LOG = LoggerFactory.getLogger(JadxArgsValidator.class);
public static void validate(JadxArgs args) {
if (args.getInputFiles().isEmpty()) {
throw new JadxRuntimeException("Please specify input file");
checkInputFiles(args);
validateOutDirs(args);
if (LOG.isDebugEnabled()) {
LOG.debug("Effective jadx args: {}", args);
}
}
private static void checkInputFiles(JadxArgs args) {
List<File> inputFiles = args.getInputFiles();
if (inputFiles.isEmpty()) {
throw new JadxArgsValidateException("Please specify input file");
}
if (inputFiles.size() > 1) {
for (File inputFile : inputFiles) {
String fileName = inputFile.getName();
if (fileName.startsWith("--")) {
throw new JadxArgsValidateException("Unknown argument: " + fileName);
}
}
throw new JadxArgsValidateException("Only one input file supported");
}
for (File file : args.getInputFiles()) {
for (File file : inputFiles) {
checkFile(file);
}
validateOutDirs(args);
}
private static void validateOutDirs(JadxArgs args) {
......@@ -71,16 +90,16 @@ public class JadxArgsValidator {
private static void checkFile(File file) {
if (!file.exists()) {
throw new JadxRuntimeException("File not found " + file.getAbsolutePath());
throw new JadxArgsValidateException("File not found " + file.getAbsolutePath());
}
if (file.isDirectory()) {
throw new JadxRuntimeException("Expected file but found directory instead: " + file.getAbsolutePath());
throw new JadxArgsValidateException("Expected file but found directory instead: " + file.getAbsolutePath());
}
}
private static void checkDir(File dir) {
if (dir != null && dir.exists() && !dir.isDirectory()) {
throw new JadxRuntimeException("Output directory exists as file " + dir);
throw new JadxArgsValidateException("Output directory exists as file " + dir);
}
}
......
package jadx.core.utils.exceptions;
public class JadxArgsValidateException extends RuntimeException {
private static final long serialVersionUID = -7457621776087311909L;
public JadxArgsValidateException(String message) {
super(message);
}
public JadxArgsValidateException(String message, Throwable cause) {
super(message, cause);
}
}
......@@ -270,7 +270,7 @@ public class JadxSettingsWindow extends JDialog {
});
JCheckBox cfg = new JCheckBox();
cfg.setSelected(settings.isCFGOutput());
cfg.setSelected(settings.isCfgOutput());
cfg.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
settings.setCfgOutput(e.getStateChange() == ItemEvent.SELECTED);
......@@ -279,7 +279,7 @@ public class JadxSettingsWindow extends JDialog {
});
JCheckBox rawCfg = new JCheckBox();
rawCfg.setSelected(settings.isRawCFGOutput());
rawCfg.setSelected(settings.isRawCfgOutput());
rawCfg.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
settings.setRawCfgOutput(e.getStateChange() == ItemEvent.SELECTED);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册