From 4edb5121215ebb8263832b19bd7d87672409d88d Mon Sep 17 00:00:00 2001 From: Christian Jones Date: Sat, 11 Jun 2022 10:40:39 -0400 Subject: [PATCH] fix(cli): allow decoding resource-only APKs (#1517)(PR #1530) * Process resource-only inputs * Fix error, add testing --- jadx-cli/src/main/java/jadx/cli/JadxCLI.java | 10 +++++-- .../src/test/java/jadx/cli/TestInput.java | 27 ++++++++++++++++++ .../test/resources/samples/resources-only.apk | Bin 0 -> 16737 bytes 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 jadx-cli/src/test/resources/samples/resources-only.apk diff --git a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java index 94cb4719..fb0882f6 100644 --- a/jadx-cli/src/main/java/jadx/cli/JadxCLI.java +++ b/jadx-cli/src/main/java/jadx/cli/JadxCLI.java @@ -66,8 +66,14 @@ public class JadxCLI { private static boolean checkForErrors(JadxDecompiler jadx) { if (jadx.getRoot().getClasses().isEmpty()) { - LOG.error("Load failed! No classes for decompile!"); - return true; + if (jadx.getArgs().isSkipResources()) { + LOG.error("Load failed! No classes for decompile!"); + return true; + } + if (!jadx.getArgs().isSkipSources()) { + LOG.warn("No classes to decompile; decoding resources only"); + jadx.getArgs().setSkipSources(true); + } } if (jadx.getErrorsCount() > 0) { LOG.error("Load with errors! Check log for details"); diff --git a/jadx-cli/src/test/java/jadx/cli/TestInput.java b/jadx-cli/src/test/java/jadx/cli/TestInput.java index 31eed72d..22f18020 100644 --- a/jadx-cli/src/test/java/jadx/cli/TestInput.java +++ b/jadx-cli/src/test/java/jadx/cli/TestInput.java @@ -44,6 +44,33 @@ public class TestInput { decompile("multi", "samples/hello.dex", "samples/HelloWorld.smali"); } + @Test + public void testResourceOnly() throws Exception { + decode("resourceOnly", "samples/resources-only.apk"); + } + + private void decode(String tmpDirName, String apkSample) throws URISyntaxException, IOException { + List args = new ArrayList<>(); + Path tempDir = FileUtils.createTempDir(tmpDirName); + args.add("-v"); + args.add("-d"); + args.add(tempDir.toAbsolutePath().toString()); + + URL resource = getClass().getClassLoader().getResource(apkSample); + assertThat(resource).isNotNull(); + String sampleFile = resource.toURI().getRawPath(); + args.add(sampleFile); + + int result = JadxCLI.execute(args.toArray(new String[0])); + assertThat(result).isEqualTo(0); + List files = Files.find( + tempDir, + 3, + (file, attr) -> file.getFileName().toString().equalsIgnoreCase("AndroidManifest.xml")) + .collect(Collectors.toList()); + assertThat(files.isEmpty()).isFalse(); + } + private void decompile(String tmpDirName, String... inputSamples) throws URISyntaxException, IOException { List args = new ArrayList<>(); Path tempDir = FileUtils.createTempDir(tmpDirName); diff --git a/jadx-cli/src/test/resources/samples/resources-only.apk b/jadx-cli/src/test/resources/samples/resources-only.apk new file mode 100644 index 0000000000000000000000000000000000000000..abf0068451db0003c8491f67d37f55c1a154a74b GIT binary patch literal 16737 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 literal 0 HcmV?d00001 -- GitLab