diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index df707949f..f9ddd2561 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -1,7 +1,6 @@ package jadx.cli; import jadx.api.JadxDecompiler; -import jadx.core.utils.ErrorsCounter; import jadx.core.utils.exceptions.JadxException; import java.io.File; @@ -12,33 +11,29 @@ import org.slf4j.LoggerFactory; public class JadxCLI { private static final Logger LOG = LoggerFactory.getLogger(JadxCLI.class); - public static void main(String[] args) { + public static void main(String[] args) throws JadxException { try { JadxCLIArgs jadxArgs = new JadxCLIArgs(); if (processArgs(jadxArgs, args)) { processAndSave(jadxArgs); } - } catch (JadxException e) { - LOG.error(e.getMessage()); + } catch (Throwable e) { + LOG.error("jadx error: " + e.getMessage(), e); System.exit(1); } } static void processAndSave(JadxCLIArgs jadxArgs) throws JadxException { - try { - JadxDecompiler jadx = new JadxDecompiler(jadxArgs); - jadx.loadFiles(jadxArgs.getInput()); - jadx.setOutputDir(jadxArgs.getOutDir()); - jadx.save(); - } catch (Throwable e) { - throw new JadxException("jadx error: " + e.getMessage(), e); + JadxDecompiler jadx = new JadxDecompiler(jadxArgs); + jadx.setOutputDir(jadxArgs.getOutDir()); + jadx.loadFiles(jadxArgs.getInput()); + jadx.save(); + if (jadx.getErrorsCount() != 0) { + jadx.printErrorsReport(); + LOG.error("finished with errors"); + } else { + LOG.info("done"); } - if (ErrorsCounter.getErrorCount() != 0) { - ErrorsCounter.printReport(); - throw new JadxException("finished with errors"); - } - LOG.info("done"); - } static boolean processArgs(JadxCLIArgs jadxArgs, String[] args) throws JadxException { diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java index 2a378296b..ccfca6000 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java @@ -1,7 +1,7 @@ package jadx.cli; import jadx.api.IJadxArgs; -import jadx.core.Consts; +import jadx.api.JadxDecompiler; import jadx.core.utils.exceptions.JadxException; import java.io.File; @@ -105,7 +105,7 @@ public final class JadxCLIArgs implements IJadxArgs { // print usage in not sorted fields order (by default its sorted by description) PrintStream out = System.out; out.println(); - out.println("jadx - dex to java decompiler, version: " + Consts.JADX_VERSION); + out.println("jadx - dex to java decompiler, version: " + JadxDecompiler.getVersion()); out.println(); out.println("usage: jadx [options] " + jc.getMainParameterDescription()); out.println("options:"); @@ -148,6 +148,7 @@ public final class JadxCLIArgs implements IJadxArgs { return input; } + @Override public File getOutDir() { return outputDir; } diff --git a/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java b/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java index 65b8b8ef8..d803bef6c 100644 --- a/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java +++ b/jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java @@ -1,7 +1,14 @@ package jadx.api; +import java.io.File; + public class DefaultJadxArgs implements IJadxArgs { + @Override + public File getOutDir() { + return new File("jadx-output"); + } + @Override public int getThreadsCount() { return Runtime.getRuntime().availableProcessors(); diff --git a/jadx-core/src/main/java/jadx/api/IJadxArgs.java b/jadx-core/src/main/java/jadx/api/IJadxArgs.java index 661983cc0..1dbc0cf52 100644 --- a/jadx-core/src/main/java/jadx/api/IJadxArgs.java +++ b/jadx-core/src/main/java/jadx/api/IJadxArgs.java @@ -1,6 +1,10 @@ package jadx.api; +import java.io.File; + public interface IJadxArgs { + File getOutDir(); + int getThreadsCount(); boolean isCFGOutput(); diff --git a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java index 49a1e8b90..ea8cd446d 100644 --- a/jadx-core/src/main/java/jadx/api/JadxDecompiler.java +++ b/jadx-core/src/main/java/jadx/api/JadxDecompiler.java @@ -7,7 +7,6 @@ import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.RootNode; import jadx.core.dex.visitors.IDexTreeVisitor; import jadx.core.dex.visitors.SaveCode; -import jadx.core.utils.ErrorsCounter; import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.JadxException; import jadx.core.utils.exceptions.JadxRuntimeException; @@ -57,12 +56,13 @@ public final class JadxDecompiler { private List classes; public JadxDecompiler() { - this.args = new DefaultJadxArgs(); - init(); + this(new DefaultJadxArgs()); } public JadxDecompiler(IJadxArgs jadxArgs) { this.args = jadxArgs; + this.outDir = jadxArgs.getOutDir(); + reset(); init(); } @@ -72,17 +72,20 @@ public final class JadxDecompiler { } void init() { - reset(); if (outDir == null) { - outDir = new File("jadx-output"); + outDir = new DefaultJadxArgs().getOutDir(); } this.passes = Jadx.getPassesList(args, outDir); } void reset() { ClassInfo.clearCache(); - ErrorsCounter.reset(); classes = null; + root = null; + } + + public static String getVersion() { + return Jadx.getVersion(); } public void loadFile(File file) throws JadxException { @@ -182,7 +185,17 @@ public final class JadxDecompiler { } public int getErrorsCount() { - return ErrorsCounter.getErrorCount(); + if (root == null) { + return 0; + } + return root.getErrorsCounter().getErrorCount(); + } + + public void printErrorsReport() { + if (root == null) { + return; + } + root.getErrorsCounter().printReport(); } void parse() throws DecodeException { @@ -214,6 +227,6 @@ public final class JadxDecompiler { @Override public String toString() { - return "jadx decompiler"; + return "jadx decompiler " + getVersion(); } } diff --git a/jadx-core/src/main/java/jadx/core/Consts.java b/jadx-core/src/main/java/jadx/core/Consts.java index c1afd7337..049406746 100644 --- a/jadx-core/src/main/java/jadx/core/Consts.java +++ b/jadx-core/src/main/java/jadx/core/Consts.java @@ -1,8 +1,6 @@ package jadx.core; public class Consts { - public static final String JADX_VERSION = Jadx.getVersion(); - public static final boolean DEBUG = false; public static final String CLASS_OBJECT = "java.lang.Object"; diff --git a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java index 844d20496..4a3eb3126 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/NameGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/NameGen.java @@ -172,7 +172,7 @@ public class NameGen { } } - public static String getAliasForObject(String name) { + private static String getAliasForObject(String name) { return OBJ_ALIAS.get(name); } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java index f7e3025da..03ca73aca 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java @@ -3,6 +3,7 @@ package jadx.core.dex.nodes; import jadx.core.clsp.ClspGraph; import jadx.core.dex.info.ClassInfo; import jadx.core.dex.instructions.args.ArgType; +import jadx.core.utils.ErrorsCounter; import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.files.InputFile; @@ -14,6 +15,7 @@ import java.util.Map; public class RootNode { private final Map names = new HashMap(); + private final ErrorsCounter errorsCounter = new ErrorsCounter(); private List dexNodes; public void load(List dexFiles) throws DecodeException { @@ -101,4 +103,8 @@ public class RootNode { String fullName = cls.getFullName(); return searchClassByName(fullName); } + + public ErrorsCounter getErrorsCounter() { + return errorsCounter; + } } diff --git a/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java b/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java index 47da988c6..50c2cbc1f 100644 --- a/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java +++ b/jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java @@ -20,20 +20,20 @@ import org.slf4j.LoggerFactory; public class ErrorsCounter { private static final Logger LOG = LoggerFactory.getLogger(ErrorsCounter.class); - private static final Set ERROR_NODES = new HashSet(); - private static int errorsCount; + private final Set errorNodes = new HashSet(); + private int errorsCount; - public static int getErrorCount() { + public int getErrorCount() { return errorsCount; } - public static void reset() { - ERROR_NODES.clear(); + public void reset() { + errorNodes.clear(); errorsCount = 0; } - private static void addError(IAttributeNode node, String msg, Throwable e) { - ERROR_NODES.add(node); + private void addError(IAttributeNode node, String msg, Throwable e) { + errorNodes.add(node); errorsCount++; if (e != null) { @@ -53,13 +53,13 @@ public class ErrorsCounter { public static String classError(ClassNode cls, String errorMsg, Throwable e) { String msg = formatErrorMsg(cls, errorMsg); - addError(cls, msg, e); + cls.dex().root().getErrorsCounter().addError(cls, msg, e); return msg; } public static String methodError(MethodNode mth, String errorMsg, Throwable e) { String msg = formatErrorMsg(mth, errorMsg); - addError(mth, msg, e); + mth.dex().root().getErrorsCounter().addError(mth, msg, e); return msg; } @@ -67,10 +67,10 @@ public class ErrorsCounter { return methodError(mth, errorMsg, null); } - public static void printReport() { + public void printReport() { if (getErrorCount() > 0) { LOG.error(getErrorCount() + " errors occured in following nodes:"); - List nodes = new ArrayList(ERROR_NODES); + List nodes = new ArrayList(errorNodes); Collections.sort(nodes, new Comparator() { @Override public int compare(Object o1, Object o2) { @@ -92,7 +92,7 @@ public class ErrorsCounter { return msg + " in method: " + mth; } - private static String formatException(Throwable e) { + private String formatException(Throwable e) { if (e == null || e.getMessage() == null) { return ""; } else { @@ -100,11 +100,11 @@ public class ErrorsCounter { } } - public static String formatErrorMsg(ClassNode cls, String msg, Throwable e) { + public String formatErrorMsg(ClassNode cls, String msg, Throwable e) { return formatErrorMsg(cls, msg) + formatException(e); } - public static String formatErrorMsg(MethodNode mth, String msg, Throwable e) { + public String formatErrorMsg(MethodNode mth, String msg, Throwable e) { return formatErrorMsg(mth, msg) + formatException(e); } } diff --git a/jadx-core/src/test/groovy/jadx/tests/TestAPI.groovy b/jadx-core/src/test/groovy/jadx/tests/TestAPI.groovy index dcdfef31b..48c4d042d 100644 --- a/jadx-core/src/test/groovy/jadx/tests/TestAPI.groovy +++ b/jadx-core/src/test/groovy/jadx/tests/TestAPI.groovy @@ -1,9 +1,6 @@ package jadx.tests - -import jadx.api.JadxDecompiler import jadx.api.IJadxArgs -import jadx.core.dex.nodes.MethodNode -import jadx.core.utils.ErrorsCounter +import jadx.api.JadxDecompiler import jadx.core.utils.exceptions.JadxException import jadx.core.utils.exceptions.JadxRuntimeException import spock.lang.Specification @@ -67,20 +64,4 @@ class TestAPI extends Specification { expect: new JadxDecompiler().getErrorsCount() == 0 } - - def "get errors count after one more init"() { - setup: - new JadxDecompiler() - def mth = Mock(MethodNode) - when: - ErrorsCounter.methodError(mth, "") - def d = new JadxDecompiler() - then: - d.getErrorsCount() == 0 - } - - def "decompiler toString()"() { - expect: - new JadxDecompiler().toString() == "jadx decompiler" - } }