diff --git a/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java b/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java index b0b29df8ed5b9cef152edf94c27f426570513c51..add89bfee20b3efed1e7ca5279426036c1083b5d 100644 --- a/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java +++ b/jadx-core/src/main/java/jadx/core/utils/files/InputFile.java @@ -10,6 +10,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Enumeration; import java.util.List; import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; @@ -81,36 +82,53 @@ public class InputFile { private boolean loadFromZip(String ext) throws IOException, DecodeException { ZipFile zf = new ZipFile(file); + + // Input file could be .apk or .zip files + // we should consider the input file could contain only one single dex, multi-dex, or instantRun support dex for Android .apk files + String instantRunDexSuffix = "classes" + ext; int index = 0; - while (true) { - String entryName = "classes" + (index == 0 ? "" : index) + ext; - ZipEntry entry = zf.getEntry(entryName); - if (entry == null) { - break; - } + for (Enumeration e = zf.entries(); e.hasMoreElements(); ) { + ZipEntry entry = e.nextElement(); + String entryName = entry.getName(); + InputStream inputStream = zf.getInputStream(entry); try { - if (ext.equals(".dex")) { - addDexFile(entryName, new Dex(inputStream)); - } else if (ext.equals(".jar")) { - File jarFile = FileUtils.createTempFile(entryName); + if ((entryName.startsWith("classes") && entryName.endsWith(ext)) || entryName.endsWith(instantRunDexSuffix)) { + if (ext.equals(".dex")) { + index++; + addDexFile(entryName, new Dex(inputStream)); + } else if (ext.equals(".jar")) { + index++; + File jarFile = FileUtils.createTempFile(entryName); + FileOutputStream fos = new FileOutputStream(jarFile); + try { + IOUtils.copy(inputStream, fos); + } finally { + close(fos); + } + addDexFile(entryName, loadFromJar(jarFile)); + } else { + throw new JadxRuntimeException("Unexpected extension in zip: " + ext); + } + } else if (entryName.equals("instant-run.zip") && ext.equals(".dex")) { + File jarFile = FileUtils.createTempFile("instant-run.zip"); FileOutputStream fos = new FileOutputStream(jarFile); try { IOUtils.copy(inputStream, fos); } finally { close(fos); } - addDexFile(entryName, loadFromJar(jarFile)); - } else { - throw new JadxRuntimeException("Unexpected extension in zip: " + ext); + InputFile tempFile = new InputFile(jarFile); + tempFile.loadFromZip(ext); + List dexFiles = tempFile.getDexFiles(); + if (!dexFiles.isEmpty()) { + index += dexFiles.size(); + this.dexFiles.addAll(dexFiles); + } } } finally { close(inputStream); } - index++; - if (index == 1) { - index = 2; - } } zf.close(); return index > 0;