Search in sources :

Example 26 with DexBackedDexFile

use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project android-classyshark by google.

the class DexInfoTranslator method apply.

@Override
public void apply() {
    try {
        elements.clear();
        File classesDex = extractClassesDex(dexFileName, apkFile, this);
        DexFile dxFile = DexlibLoader.loadDexFile(classesDex);
        DexBackedDexFile dataPack = (DexBackedDexFile) dxFile;
        ELEMENT element = new ELEMENT("\nclasses: " + dataPack.getClassCount(), TAG.MODIFIER);
        elements.add(element);
        element = new ELEMENT("\nstrings: " + dataPack.getStringCount(), TAG.DOCUMENT);
        elements.add(element);
        element = new ELEMENT("\ntypes: " + dataPack.getTypeCount(), TAG.DOCUMENT);
        elements.add(element);
        element = new ELEMENT("\nprotos: " + dataPack.getProtoCount(), TAG.DOCUMENT);
        elements.add(element);
        element = new ELEMENT("\nfields: " + dataPack.getFieldCount(), TAG.DOCUMENT);
        elements.add(element);
        element = new ELEMENT("\nmethods: " + dataPack.getMethodCount(), TAG.IDENTIFIER);
        elements.add(element);
        element = new ELEMENT("\n\nFile size: " + JarInfoTranslator.readableFileSize(classesDex.length()), TAG.DOCUMENT);
        elements.add(element);
        element = new ELEMENT("\n\nClasses with Native Calls\n", TAG.MODIFIER);
        elements.add(element);
        Set<String> classesWithNativeMethods = getClassesWithNativeMethodsPerDexIndex(index, classesDex);
        for (String classWithNativeMethods : classesWithNativeMethods) {
            element = new ELEMENT(classWithNativeMethods + "\n", TAG.DOCUMENT);
            elements.add(element);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) DexFile(org.jf.dexlib2.iface.DexFile)

Example 27 with DexBackedDexFile

use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project tinker by Tencent.

the class DexDiffDecoder method generateChangedClassesDexFile.

@SuppressWarnings("NewApi")
private void generateChangedClassesDexFile() throws IOException {
    final String dexMode = config.mDexRaw ? "raw" : "jar";
    List<File> oldDexList = new ArrayList<>();
    List<File> newDexList = new ArrayList<>();
    for (AbstractMap.SimpleEntry<File, File> oldAndNewDexFilePair : oldAndNewDexFilePairList) {
        File oldDexFile = oldAndNewDexFilePair.getKey();
        File newDexFile = oldAndNewDexFilePair.getValue();
        if (oldDexFile != null) {
            oldDexList.add(oldDexFile);
        }
        if (newDexFile != null) {
            newDexList.add(newDexFile);
        }
    }
    DexGroup oldDexGroup = DexGroup.wrap(oldDexList);
    DexGroup newDexGroup = DexGroup.wrap(newDexList);
    ChangedClassesDexClassInfoCollector collector = new ChangedClassesDexClassInfoCollector();
    collector.setExcludedClassPatterns(config.mDexLoaderPattern);
    collector.setLogger(dexPatcherLoggerBridge);
    collector.setIncludeRefererToRefererAffectedClasses(true);
    Set<DexClassInfo> classInfosInChangedClassesDex = collector.doCollect(oldDexGroup, newDexGroup);
    Set<Dex> owners = new HashSet<>();
    Map<Dex, Set<String>> ownerToDescOfChangedClassesMap = new HashMap<>();
    for (DexClassInfo classInfo : classInfosInChangedClassesDex) {
        owners.add(classInfo.owner);
        Set<String> descOfChangedClasses = ownerToDescOfChangedClassesMap.get(classInfo.owner);
        if (descOfChangedClasses == null) {
            descOfChangedClasses = new HashSet<>();
            ownerToDescOfChangedClassesMap.put(classInfo.owner, descOfChangedClasses);
        }
        descOfChangedClasses.add(classInfo.classDesc);
    }
    StringBuilder metaBuilder = new StringBuilder();
    int changedDexId = 1;
    for (Dex dex : owners) {
        Set<String> descOfChangedClassesInCurrDex = ownerToDescOfChangedClassesMap.get(dex);
        DexFile dexFile = new DexBackedDexFile(org.jf.dexlib2.Opcodes.forApi(20), dex.getBytes());
        boolean isCurrentDexHasChangedClass = false;
        for (org.jf.dexlib2.iface.ClassDef classDef : dexFile.getClasses()) {
            if (descOfChangedClassesInCurrDex.contains(classDef.getType())) {
                isCurrentDexHasChangedClass = true;
                break;
            }
        }
        if (!isCurrentDexHasChangedClass) {
            continue;
        }
        DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(23));
        for (org.jf.dexlib2.iface.ClassDef classDef : dexFile.getClasses()) {
            if (!descOfChangedClassesInCurrDex.contains(classDef.getType())) {
                continue;
            }
            Logger.d("Class %s will be added into changed classes dex ...", classDef.getType());
            List<BuilderField> builderFields = new ArrayList<>();
            for (Field field : classDef.getFields()) {
                final BuilderField builderField = dexBuilder.internField(field.getDefiningClass(), field.getName(), field.getType(), field.getAccessFlags(), field.getInitialValue(), field.getAnnotations());
                builderFields.add(builderField);
            }
            List<BuilderMethod> builderMethods = new ArrayList<>();
            for (Method method : classDef.getMethods()) {
                MethodImplementation methodImpl = method.getImplementation();
                if (methodImpl != null) {
                    methodImpl = new BuilderMutableMethodImplementation(dexBuilder, methodImpl);
                }
                BuilderMethod builderMethod = dexBuilder.internMethod(method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), methodImpl);
                builderMethods.add(builderMethod);
            }
            dexBuilder.internClassDef(classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), builderFields, builderMethods);
        }
        // Write constructed changed classes dex to file and record it in meta file.
        String changedDexName = null;
        if (changedDexId == 1) {
            changedDexName = "classes.dex";
        } else {
            changedDexName = "classes" + changedDexId + ".dex";
        }
        final File dest = new File(config.mTempResultDir + "/" + changedDexName);
        final FileDataStore fileDataStore = new FileDataStore(dest);
        dexBuilder.writeTo(fileDataStore);
        final String md5 = MD5.getMD5(dest);
        appendMetaLine(metaBuilder, changedDexName, "", md5, md5, 0, 0, 0, dexMode);
        ++changedDexId;
    }
    final String meta = metaBuilder.toString();
    Logger.d("\nDexDecoder:write changed classes dex meta file data:\n%s", meta);
    metaWriter.writeLineToInfoFile(meta);
}
Also used : DexGroup(com.tencent.tinker.build.util.DexClassesComparator.DexGroup) MethodImplementation(org.jf.dexlib2.iface.MethodImplementation) BuilderMutableMethodImplementation(org.jf.dexlib2.builder.BuilderMutableMethodImplementation) Set(java.util.Set) HashSet(java.util.HashSet) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AbstractMap(java.util.AbstractMap) BuilderField(org.jf.dexlib2.writer.builder.BuilderField) Field(org.jf.dexlib2.iface.Field) BuilderField(org.jf.dexlib2.writer.builder.BuilderField) FileDataStore(org.jf.dexlib2.writer.io.FileDataStore) HashSet(java.util.HashSet) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) ChangedClassesDexClassInfoCollector(com.tencent.tinker.build.dexpatcher.util.ChangedClassesDexClassInfoCollector) BuilderMutableMethodImplementation(org.jf.dexlib2.builder.BuilderMutableMethodImplementation) Method(org.jf.dexlib2.iface.Method) BuilderMethod(org.jf.dexlib2.writer.builder.BuilderMethod) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) DexBuilder(org.jf.dexlib2.writer.builder.DexBuilder) Dex(com.tencent.tinker.android.dex.Dex) BuilderMethod(org.jf.dexlib2.writer.builder.BuilderMethod) JarFile(java.util.jar.JarFile) DexFile(org.jf.dexlib2.iface.DexFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File) DexClassInfo(com.tencent.tinker.build.util.DexClassesComparator.DexClassInfo)

Example 28 with DexBackedDexFile

use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project dex2jar by pxb1988.

the class SmaliTest method dotest.

private void dotest(File dexFile) throws IOException {
    DexBackedDexFile dex;
    try {
        dex = DexFileFactory.loadDexFile(dexFile, 14, false);
    } catch (DexBackedDexFile.NotADexFile ex) {
        ex.printStackTrace();
        return;
    }
    Map<String, DexClassNode> map = readDex(dexFile);
    for (DexBackedClassDef def : dex.getClasses()) {
        String type = def.getType();
        System.out.println(type);
        DexClassNode dexClassNode = map.get(type);
        Assert.assertNotNull(dexClassNode);
        // original
        String smali = baksmali(def);
        Smali.smaliFile2Node("fake.smali", smali);
        {
            byte[] data = toDex(dexClassNode);
            DexBackedClassDef def2 = new DexBackedDexFile(new Opcodes(14, false), data).getClasses().iterator().next();
            // original
            String baksmali3 = baksmali(def2);
            Assert.assertEquals(smali, baksmali3);
        }
        String psmali = pbaksmali(dexClassNode);
        DexClassNode dexClassNode2 = Smali.smaliFile2Node("fake.smali", psmali);
        Assert.assertEquals("cmp smalip", psmali, pbaksmali(dexClassNode2));
        {
            byte[] data = toDex(dexClassNode2);
            DexBackedClassDef def2 = new DexBackedDexFile(new Opcodes(14, false), data).getClasses().iterator().next();
            // original
            String baksmali3 = baksmali(def2);
            Assert.assertEquals(smali, baksmali3);
        }
    }
}
Also used : DexClassNode(com.googlecode.d2j.node.DexClassNode) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) Opcodes(org.jf.dexlib2.Opcodes) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 29 with DexBackedDexFile

use of org.jf.dexlib2.dexbacked.DexBackedDexFile 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, @Nullable 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, new FilenameVdexProvider(file));
        } 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 30 with DexBackedDexFile

use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.

the class DexWriterTest method testAnnotationElementOrder.

@Test
public void testAnnotationElementOrder() {
    // Elements are out of order wrt to the element name
    ImmutableSet<ImmutableAnnotationElement> elements = ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE), new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE));
    ImmutableAnnotation annotation = new ImmutableAnnotation(AnnotationVisibility.RUNTIME, "Lorg/test/anno;", elements);
    ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null);
    MemoryDataStore dataStore = new MemoryDataStore();
    try {
        DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.getDefault(), ImmutableSet.of(classDef)));
    } catch (IOException ex) {
        throw new RuntimeException(ex);
    }
    DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getBuffer());
    ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
    Assert.assertNotNull(dbClassDef);
    Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
    Assert.assertNotNull(dbAnnotation);
    List<AnnotationElement> dbElements = Lists.newArrayList(dbAnnotation.getElements());
    // Ensure that the elements were written out in sorted order
    Assert.assertEquals(2, dbElements.size());
    Assert.assertEquals("blah", dbElements.get(0).getName());
    Assert.assertEquals("zabaglione", dbElements.get(1).getName());
}
Also used : DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) ImmutableAnnotationElement(org.jf.dexlib2.immutable.ImmutableAnnotationElement) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) MemoryDataStore(org.jf.dexlib2.writer.io.MemoryDataStore) IOException(java.io.IOException) ImmutableAnnotation(org.jf.dexlib2.immutable.ImmutableAnnotation) Annotation(org.jf.dexlib2.iface.Annotation) ImmutableAnnotation(org.jf.dexlib2.immutable.ImmutableAnnotation) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) ImmutableAnnotationElement(org.jf.dexlib2.immutable.ImmutableAnnotationElement) AnnotationElement(org.jf.dexlib2.iface.AnnotationElement) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) Test(org.junit.Test)

Aggregations

DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)29 Test (org.junit.Test)10 IOException (java.io.IOException)9 File (java.io.File)7 MemoryDataStore (org.jf.dexlib2.writer.io.MemoryDataStore)6 ClassDef (org.jf.dexlib2.iface.ClassDef)5 DexFile (org.jf.dexlib2.iface.DexFile)5 Nonnull (javax.annotation.Nonnull)4 DexEntryFinder (org.jf.dexlib2.DexFileFactory.DexEntryFinder)4 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)4 DexBuilder (org.jf.dexlib2.writer.builder.DexBuilder)4 ArrayList (java.util.ArrayList)3 NotNull (org.jetbrains.annotations.NotNull)3 FileInputStream (java.io.FileInputStream)2 Opcode (org.jf.dexlib2.Opcode)2 Opcodes (org.jf.dexlib2.Opcodes)2 ClassPath (org.jf.dexlib2.analysis.ClassPath)2 ClassPathResolver (org.jf.dexlib2.analysis.ClassPathResolver)2 BuilderInstruction21c (org.jf.dexlib2.builder.instruction.BuilderInstruction21c)2 DexBackedOdexFile (org.jf.dexlib2.dexbacked.DexBackedOdexFile)2