mirror of
https://github.com/revanced/smali.git
synced 2025-05-08 10:24:31 +02:00
The list dex command should generate an error when used on a non-zip/oat file
This commit is contained in:
parent
d7d995cc2d
commit
fbfe388e40
@ -35,20 +35,15 @@ import com.beust.jcommander.JCommander;
|
|||||||
import com.beust.jcommander.Parameter;
|
import com.beust.jcommander.Parameter;
|
||||||
import com.beust.jcommander.Parameters;
|
import com.beust.jcommander.Parameters;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jf.dexlib2.dexbacked.OatFile;
|
import org.jf.dexlib2.DexFileFactory;
|
||||||
import org.jf.dexlib2.dexbacked.raw.HeaderItem;
|
|
||||||
import org.jf.dexlib2.dexbacked.raw.OdexHeaderItem;
|
|
||||||
import org.jf.util.jcommander.Command;
|
import org.jf.util.jcommander.Command;
|
||||||
import org.jf.util.jcommander.ExtendedParameter;
|
import org.jf.util.jcommander.ExtendedParameter;
|
||||||
import org.jf.util.jcommander.ExtendedParameters;
|
import org.jf.util.jcommander.ExtendedParameters;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.Collections;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
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.")
|
@Parameters(commandDescription = "Lists the dex files in an apk/oat file.")
|
||||||
@ExtendedParameters(
|
@ExtendedParameters(
|
||||||
@ -85,53 +80,18 @@ public class ListDexCommand extends Command {
|
|||||||
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
System.err.println(String.format("Could not find the file: %s", input));
|
System.err.println(String.format("Could not find the file: %s", input));
|
||||||
|
System.exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> entries;
|
||||||
try {
|
try {
|
||||||
ZipFile zipFile = new ZipFile(input);
|
entries = DexFileFactory.getAllDexEntries(file);
|
||||||
|
|
||||||
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
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new RuntimeException(ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
for (String entry: entries) {
|
||||||
InputStream inputStream = new BufferedInputStream(new FileInputStream(input));
|
System.out.println(entry);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ import com.google.common.base.Joiner;
|
|||||||
import com.google.common.collect.AbstractIterator;
|
import com.google.common.collect.AbstractIterator;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile;
|
||||||
|
import org.jf.dexlib2.dexbacked.DexBackedDexFile.NotADexFile;
|
||||||
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
import org.jf.dexlib2.dexbacked.DexBackedOdexFile;
|
||||||
import org.jf.dexlib2.dexbacked.OatFile;
|
import org.jf.dexlib2.dexbacked.OatFile;
|
||||||
import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
|
import org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException;
|
||||||
@ -249,10 +250,10 @@ public final class DexFileFactory {
|
|||||||
*
|
*
|
||||||
* @param file The file to open
|
* @param file The file to open
|
||||||
* @param opcodes The set of opcodes to use
|
* @param opcodes The set of opcodes to use
|
||||||
* @return A DexBackedDexFile for the given file
|
* @return An iterable of DexBackedDexFiles
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws DexFileNotFoundException If the given file does not exist
|
* @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(
|
public static Iterable<? extends DexBackedDexFile> loadAllDexFiles(
|
||||||
@Nonnull File file, @Nonnull final Opcodes opcodes) throws IOException {
|
@Nonnull File file, @Nonnull final Opcodes opcodes) throws IOException {
|
||||||
@ -284,6 +285,8 @@ public final class DexFileFactory {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new ExceptionWithContext(ex, "Error while reading %s from %s",
|
throw new ExceptionWithContext(ex, "Error while reading %s from %s",
|
||||||
zipEntry.getName(), finalZipFile.getName());
|
zipEntry.getName(), finalZipFile.getName());
|
||||||
|
} catch (NotADexFile ex) {
|
||||||
|
// ignore and continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -331,7 +334,80 @@ public final class DexFileFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
throw new UnsupportedFileTypeException("%s is not an apk, dex, odex or oat file.", file.getPath());
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user