diff --git a/.gitignore b/.gitignore index e87f7d17f..ead4e1c4f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,3 @@ jadx-output/ *.dump *.log *.cfg - -jadx-core/src/test/java/jadx/tests/external/ diff --git a/jadx-core/build.gradle b/jadx-core/build.gradle index b4aced120..54c5dc951 100644 --- a/jadx-core/build.gradle +++ b/jadx-core/build.gradle @@ -11,5 +11,7 @@ dependencies { testCompile 'org.smali:smali:2.2.2' testCompile 'org.smali:baksmali:2.2.2' + + testCompile 'org.apache.commons:commons-lang3:3.7' } diff --git a/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java b/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java index 37f607c34..bbaea4aae 100644 --- a/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java +++ b/jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java @@ -48,6 +48,14 @@ public abstract class IntegrationTest extends TestUtils { private static final String TEST_DIRECTORY = "src/test/java"; private static final String TEST_DIRECTORY2 = "jadx-core/" + TEST_DIRECTORY; + /** + * Run auto check method if defined: + *
+ * public static void check() + *+ */ + public static final String CHECK_METHOD_NAME = "check"; + protected JadxArgs args; protected boolean deleteTmpFiles = true; @@ -159,7 +167,7 @@ public abstract class IntegrationTest extends TestUtils { } Method checkMth; try { - checkMth = origCls.getMethod("check"); + checkMth = origCls.getMethod(CHECK_METHOD_NAME); } catch (NoSuchMethodException e) { // ignore return; @@ -173,7 +181,7 @@ public abstract class IntegrationTest extends TestUtils { try { checkMth.invoke(origCls.newInstance()); } catch (InvocationTargetException ie) { - rethrow("Java check failed", ie); + rethrow("Original check failed", ie); } // run 'check' method from decompiled class try { diff --git a/jadx-core/src/test/java/jadx/tests/external/.gitignore b/jadx-core/src/test/java/jadx/tests/external/.gitignore new file mode 100644 index 000000000..810fe2873 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/external/.gitignore @@ -0,0 +1 @@ +/ExternalTests.java diff --git a/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java b/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java new file mode 100644 index 000000000..e1d59882f --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/external/BaseExternalTest.java @@ -0,0 +1,141 @@ +package jadx.tests.external; + +import java.io.File; +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jadx.api.JadxArgs; +import jadx.api.JadxDecompiler; +import jadx.api.JadxInternalAccess; +import jadx.api.JavaClass; +import jadx.core.Jadx; +import jadx.core.codegen.CodeGen; +import jadx.core.codegen.CodeWriter; +import jadx.core.dex.nodes.ClassNode; +import jadx.core.dex.nodes.MethodNode; +import jadx.core.dex.nodes.RootNode; +import jadx.core.dex.visitors.DepthTraversal; +import jadx.core.dex.visitors.IDexTreeVisitor; +import jadx.core.utils.exceptions.JadxRuntimeException; +import jadx.tests.api.IntegrationTest; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public abstract class BaseExternalTest extends IntegrationTest { + private static final Logger LOG = LoggerFactory.getLogger(BaseExternalTest.class); + + protected abstract String getSamplesDir(); + + protected JadxArgs prepare(String inputFile) { + JadxArgs args = new JadxArgs(); + args.getInputFiles().add(new File(getSamplesDir(), inputFile)); + args.setOutDir(new File("../jadx-external-tests-tmp")); + return args; + } + + protected void decompile(JadxArgs jadxArgs) { + decompile(jadxArgs, null, null); + } + + protected void decompile(JadxArgs jadxArgs, String clsPatternStr) { + decompile(jadxArgs, clsPatternStr, null); + } + + protected void decompile(JadxArgs jadxArgs, @Nullable String clsPatternStr, @Nullable String mthPatternStr) { + JadxDecompiler jadx = new JadxDecompiler(jadxArgs); + jadx.load(); + + if (clsPatternStr == null) { + processAll(jadx); +// jadx.saveSources(); + } else { + Pattern clsPtrn = Pattern.compile(clsPatternStr); + Pattern mthPtrn = mthPatternStr == null ? null : Pattern.compile(mthPatternStr); + processMthByPatterns(jadx, clsPtrn, mthPtrn); + } + printErrorReport(jadx); + } + + private void processAll(JadxDecompiler jadx) { + for (JavaClass javaClass : jadx.getClasses()) { + javaClass.decompile(); + } + } + + private void processMthByPatterns(JadxDecompiler jadx, Pattern clsPattern, @Nullable Pattern mthPattern) { + List