The list dex command should generate an error when used on a non-zip/oat file
diff --git a/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java b/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java
index 65aa1ec..435d554 100644
--- a/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java
+++ b/baksmali/src/main/java/org/jf/baksmali/ListDexCommand.java
@@ -35,20 +35,15 @@
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.Lists;
-import org.jf.dexlib2.dexbacked.OatFile;
-import org.jf.dexlib2.dexbacked.raw.HeaderItem;
-import org.jf.dexlib2.dexbacked.raw.OdexHeaderItem;
+import org.jf.dexlib2.DexFileFactory;
import org.jf.util.jcommander.Command;
import org.jf.util.jcommander.ExtendedParameter;
import org.jf.util.jcommander.ExtendedParameters;
import javax.annotation.Nonnull;
-import java.io.*;
-import java.util.Collections;
+import java.io.File;
+import java.io.IOException;
import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
@Parameters(commandDescription = "Lists the dex files in an apk/oat file.")
@ExtendedParameters(
@@ -85,53 +80,18 @@
if (!file.exists()) {
System.err.println(String.format("Could not find the file: %s", input));
+ System.exit(-1);
}
+ List<String> entries;
try {
- ZipFile zipFile = new ZipFile(input);
-
- byte[] magic = new byte[8];
-
- for (ZipEntry zipEntry : Collections.list(zipFile.entries())) {
- try {
- InputStream inputStream = zipFile.getInputStream(zipEntry);
-
- int totalBytesRead = 0;
- while (totalBytesRead < 8) {
- int bytesRead = inputStream.read(magic, totalBytesRead, 8 - totalBytesRead);
- if (bytesRead == -1) {
- break;
- }
- totalBytesRead += bytesRead;
- }
-
- if (totalBytesRead == 8) {
- if (HeaderItem.verifyMagic(magic, 0) || OdexHeaderItem.verifyMagic(magic)) {
- System.out.println(zipEntry.getName());
- }
- }
- } catch (ZipException ex) {
- // ignore and keep looking
- continue;
- }
- }
- } catch (ZipException ex) {
- // ignore
+ entries = DexFileFactory.getAllDexEntries(file);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
- try {
- InputStream inputStream = new BufferedInputStream(new FileInputStream(input));
- OatFile oatFile = OatFile.fromInputStream(inputStream);
-
- for (OatFile.OatDexFile oatDexFile: oatFile.getDexFiles()) {
- System.out.println(oatDexFile.filename);
- }
- } catch (OatFile.NotAnOatFileException ex) {
- // just eat it
- } catch (IOException ex) {
- throw new RuntimeException(ex);
+ for (String entry: entries) {
+ System.out.println(entry);
}
}
}
diff --git a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
index 4bb9f9f..81c7310 100644
--- a/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
+++ b/dexlib2/src/main/java/org/jf/dexlib2/DexFileFactory.java
@@ -35,6 +35,7 @@
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Lists;
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
+import org.jf.dexlib2.dexbacked.DexBackedDexFile.NotADexFile;
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
import org.jf.dexlib2.dexbacked.OatFile;
import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
@@ -249,10 +250,10 @@
*
* @param file The file to open
* @param opcodes The set of opcodes to use
- * @return A DexBackedDexFile for the given file
+ * @return An iterable of DexBackedDexFiles
* @throws IOException
* @throws DexFileNotFoundException If the given file does not exist
- * @throws UnsupportedFileTypeException If the given file is not a dex, odex, zip or oat file
+ * @throws UnsupportedFileTypeException If the given file is not a zip or oat file
*/
public static Iterable<? extends DexBackedDexFile> loadAllDexFiles(
@Nonnull File file, @Nonnull final Opcodes opcodes) throws IOException {
@@ -284,6 +285,8 @@
} catch (IOException ex) {
throw new ExceptionWithContext(ex, "Error while reading %s from %s",
zipEntry.getName(), finalZipFile.getName());
+ } catch (NotADexFile ex) {
+ // ignore and continue
}
}
}
@@ -331,7 +334,80 @@
}
throw new UnsupportedFileTypeException("%s is not an apk, dex, odex or oat file.", file.getPath());
+ }
+ /**
+ * Gets all dex entries from an oat/zip file.
+ *
+ * For zip files, only entries that match classes[0-9]*.dex will be returned.
+ *
+ * @param file The file to get dex entries from
+
+ * @return A list of strings contains the dex entry names
+ * @throws IOException
+ * @throws DexFileNotFoundException If the given file does not exist
+ * @throws UnsupportedFileTypeException If the given file is not a zip or oat file
+ */
+ public static List<String> getAllDexEntries(@Nonnull File file) throws IOException {
+ if (!file.exists()) {
+ throw new DexFileNotFoundException("%s does not exist", file.getName());
+ }
+
+ List<String> entries = Lists.newArrayList();
+ Opcodes opcodes = Opcodes.forApi(15);
+
+ ZipFile zipFile = null;
+ try {
+ zipFile = new ZipFile(file);
+ } catch (IOException ex) {
+ // ignore and continue
+ }
+
+ if (zipFile != null) {
+ Pattern dexPattern = Pattern.compile("classes[0-9]*.dex");
+ Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
+
+ while (zipEntries.hasMoreElements()) {
+ ZipEntry zipEntry = zipEntries.nextElement();
+ if (dexPattern.matcher(zipEntry.getName()).matches()) {
+ try {
+ loadDexFromZip(zipFile, zipEntry, opcodes);
+ entries.add(zipEntry.getName());
+ } catch (IOException ex) {
+ throw new IOException(String.format("Error while reading %s from %s",
+ zipEntry.getName(), zipFile.getName()), ex);
+ }catch (NotADexFile ex) {
+ // ignore and continue
+ }
+ }
+ }
+ return entries;
+ }
+
+ InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
+ try {
+ OatFile oatFile = null;
+ try {
+ oatFile = OatFile.fromInputStream(inputStream);
+ } catch (NotAnOatFileException ex) {
+ // just eat it
+ }
+
+ if (oatFile != null) {
+ if (oatFile.isSupportedVersion() == OatFile.UNSUPPORTED) {
+ throw new UnsupportedOatVersionException(oatFile);
+ }
+
+ for (OatDexFile oatDexFile: oatFile.getDexFiles()) {
+ entries.add(oatDexFile.filename);
+ }
+ return entries;
+ }
+ } finally {
+ inputStream.close();
+ }
+
+ throw new UnsupportedFileTypeException("%s is not an apk, oat file.", file.getPath());
}
/**