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);
}
}
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());
}
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);
}
Aggregations