From e53a72c5f5d1efbd19741da7359834fada1b1801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=AD=E5=BB=BA=E5=B8=85?= Date: Thu, 12 May 2016 18:40:00 +0800 Subject: [PATCH] support for Android InstantRun Apk we should consider the input file could contain only one single dex, multi-dex, or instantRun support dex for Android .apk files --- .../java/jadx/core/utils/files/InputFile.java | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) 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 b0b29df8e..add89bfee 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;