Search in sources :

Example 1 with MultiDexContainer

use of org.jf.dexlib2.iface.MultiDexContainer in project smali by JesusFreke.

the class ListDexCommand method run.

@Override
public void run() {
    if (help || inputList == null || inputList.isEmpty()) {
        usage();
        return;
    }
    if (inputList.size() > 1) {
        System.err.println("Too many files specified");
        usage();
        return;
    }
    String input = inputList.get(0);
    File file = new File(input);
    if (!file.exists()) {
        System.err.println(String.format("Could not find the file: %s", input));
        System.exit(-1);
    }
    List<String> entries;
    try {
        MultiDexContainer<? extends DexBackedDexFile> container = DexFileFactory.loadDexContainer(file, Opcodes.getDefault());
        entries = container.getDexEntryNames();
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
    for (String entry : entries) {
        System.out.println(entry);
    }
}
Also used : IOException(java.io.IOException) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File)

Example 2 with MultiDexContainer

use of org.jf.dexlib2.iface.MultiDexContainer in project smali by JesusFreke.

the class DexFileFactory method loadDexContainer.

/**
     * Loads a file containing 1 or more dex files
     *
     * If the given file is a dex or odex file, it will return a MultiDexContainer containing that single entry.
     * Otherwise, for an oat or zip file, it will return an OatFile or ZipDexContainer respectively.
     *
     * @param file The file to open
     * @param opcodes The set of opcodes to use
     * @return A MultiDexContainer
     * @throws DexFileNotFoundException If the given file does not exist
     * @throws UnsupportedFileTypeException If the given file is not a valid dex/zip/odex/oat file
     */
public static MultiDexContainer<? extends DexBackedDexFile> loadDexContainer(@Nonnull File file, @Nonnull final Opcodes opcodes) throws IOException {
    if (!file.exists()) {
        throw new DexFileNotFoundException("%s does not exist", file.getName());
    }
    ZipDexContainer zipDexContainer = new ZipDexContainer(file, opcodes);
    if (zipDexContainer.isZipFile()) {
        return zipDexContainer;
    }
    InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
    try {
        try {
            DexBackedDexFile dexFile = DexBackedDexFile.fromInputStream(opcodes, inputStream);
            return new SingletonMultiDexContainer(file.getPath(), dexFile);
        } catch (DexBackedDexFile.NotADexFile ex) {
        // just eat it
        }
        try {
            DexBackedOdexFile odexFile = DexBackedOdexFile.fromInputStream(opcodes, inputStream);
            return new SingletonMultiDexContainer(file.getPath(), odexFile);
        } catch (DexBackedOdexFile.NotAnOdexFile ex) {
        // just eat it
        }
        // Note: DexBackedDexFile.fromInputStream and DexBackedOdexFile.fromInputStream will reset inputStream
        // back to the same position, if they fails
        OatFile oatFile = null;
        try {
            oatFile = OatFile.fromInputStream(inputStream);
        } catch (NotAnOatFileException ex) {
        // just eat it
        }
        if (oatFile != null) {
            // TODO: we should support loading earlier oat files, just not deodexing them
            if (oatFile.isSupportedVersion() == OatFile.UNSUPPORTED) {
                throw new UnsupportedOatVersionException(oatFile);
            }
            return oatFile;
        }
    } finally {
        inputStream.close();
    }
    throw new UnsupportedFileTypeException("%s is not an apk, dex, odex or oat file.", file.getPath());
}
Also used : NotAnOatFileException(org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) OatFile(org.jf.dexlib2.dexbacked.OatFile) NotADexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile.NotADexFile) ZipDexContainer(org.jf.dexlib2.dexbacked.ZipDexContainer) DexBackedOdexFile(org.jf.dexlib2.dexbacked.DexBackedOdexFile)

Example 3 with MultiDexContainer

use of org.jf.dexlib2.iface.MultiDexContainer in project soot by Sable.

the class DexFileProvider method mappingForFile.

/**
 * @param dexSourceFile A file containing either one or multiple dex files (apk, zip, etc.) but no directory!
 * @return
 * @throws IOException
 */
private Map<String, DexContainer> mappingForFile(File dexSourceFile) throws IOException {
    int api = Scene.v().getAndroidAPIVersion();
    boolean multiple_dex = Options.v().process_multiple_dex();
    // load dex files from apk/folder/file
    MultiDexContainer<? extends DexBackedDexFile> dexContainer = DexFileFactory.loadDexContainer(dexSourceFile, Opcodes.forApi(api));
    List<String> dexEntryNameList = dexContainer.getDexEntryNames();
    int dexFileCount = dexEntryNameList.size();
    if (dexFileCount < 1) {
        if (Options.v().verbose())
            logger.debug("" + String.format("Warning: No dex file found in '%s'", dexSourceFile));
        return Collections.emptyMap();
    }
    Map<String, DexContainer> dexMap = new HashMap<>(dexFileCount);
    // report found dex files and add to list.
    // We do this in reverse order to make sure that we add the first entry if there is no classes.dex file in single dex mode
    ListIterator<String> entryNameIterator = dexEntryNameList.listIterator(dexFileCount);
    while (entryNameIterator.hasPrevious()) {
        String entryName = entryNameIterator.previous();
        DexBackedDexFile entry = dexContainer.getEntry(entryName);
        entryName = deriveDexName(entryName);
        logger.debug("" + String.format("Found dex file '%s' with %d classes in '%s'", entryName, entry.getClasses().size(), dexSourceFile.getCanonicalPath()));
        if (multiple_dex)
            dexMap.put(entryName, new DexContainer(entry, entryName, dexSourceFile));
        else if (dexMap.isEmpty() && (entryName.equals("classes.dex") || !entryNameIterator.hasPrevious())) {
            // We prefer to have classes.dex in single dex mode.
            // If we haven't found a classes.dex until the last element, take the last!
            dexMap = Collections.singletonMap(entryName, new DexContainer(entry, entryName, dexSourceFile));
            if (dexFileCount > 1)
                logger.warn("Multiple dex files detected, only processing '" + entryName + "'. Use '-process-multiple-dex' option to process them all.");
        }
    }
    return Collections.unmodifiableMap(dexMap);
}
Also used : MultiDexContainer(org.jf.dexlib2.iface.MultiDexContainer) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile)

Aggregations

DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)3 File (java.io.File)1 IOException (java.io.IOException)1 NotADexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile.NotADexFile)1 DexBackedOdexFile (org.jf.dexlib2.dexbacked.DexBackedOdexFile)1 OatFile (org.jf.dexlib2.dexbacked.OatFile)1 NotAnOatFileException (org.jf.dexlib2.dexbacked.OatFile.NotAnOatFileException)1 ZipDexContainer (org.jf.dexlib2.dexbacked.ZipDexContainer)1 MultiDexContainer (org.jf.dexlib2.iface.MultiDexContainer)1