Search in sources :

Example 31 with DexBackedDexFile

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

the class DexEntryFinderTest method testNormalStuff.

@Test
public void testNormalStuff() throws Exception {
    Map<String, DexBackedDexFile> entries = Maps.newHashMap();
    DexBackedDexFile dexFile1 = mock(DexBackedDexFile.class);
    entries.put("/system/framework/framework.jar", dexFile1);
    DexBackedDexFile dexFile2 = mock(DexBackedDexFile.class);
    entries.put("/system/framework/framework.jar:classes2.dex", dexFile2);
    DexEntryFinder testFinder = new DexEntryFinder("blah.oat", new TestMultiDexContainer(entries));
    Assert.assertEquals(dexFile1, testFinder.findEntry("/system/framework/framework.jar", true).getDexFile());
    assertEntryNotFound(testFinder, "system/framework/framework.jar", true);
    assertEntryNotFound(testFinder, "/framework/framework.jar", true);
    assertEntryNotFound(testFinder, "framework/framework.jar", true);
    assertEntryNotFound(testFinder, "/framework.jar", true);
    assertEntryNotFound(testFinder, "framework.jar", true);
    Assert.assertEquals(dexFile1, testFinder.findEntry("system/framework/framework.jar", false).getDexFile());
    Assert.assertEquals(dexFile1, testFinder.findEntry("/framework/framework.jar", false).getDexFile());
    Assert.assertEquals(dexFile1, testFinder.findEntry("framework/framework.jar", false).getDexFile());
    Assert.assertEquals(dexFile1, testFinder.findEntry("/framework.jar", false).getDexFile());
    Assert.assertEquals(dexFile1, testFinder.findEntry("framework.jar", false).getDexFile());
    assertEntryNotFound(testFinder, "ystem/framework/framework.jar", false);
    assertEntryNotFound(testFinder, "ssystem/framework/framework.jar", false);
    assertEntryNotFound(testFinder, "ramework/framework.jar", false);
    assertEntryNotFound(testFinder, "ramework.jar", false);
    assertEntryNotFound(testFinder, "framework", false);
    Assert.assertEquals(dexFile2, testFinder.findEntry("/system/framework/framework.jar:classes2.dex", true).getDexFile());
    assertEntryNotFound(testFinder, "system/framework/framework.jar:classes2.dex", true);
    assertEntryNotFound(testFinder, "framework.jar:classes2.dex", true);
    assertEntryNotFound(testFinder, "classes2.dex", true);
    Assert.assertEquals(dexFile2, testFinder.findEntry("system/framework/framework.jar:classes2.dex", false).getDexFile());
    Assert.assertEquals(dexFile2, testFinder.findEntry("/framework/framework.jar:classes2.dex", false).getDexFile());
    Assert.assertEquals(dexFile2, testFinder.findEntry("framework/framework.jar:classes2.dex", false).getDexFile());
    Assert.assertEquals(dexFile2, testFinder.findEntry("/framework.jar:classes2.dex", false).getDexFile());
    Assert.assertEquals(dexFile2, testFinder.findEntry("framework.jar:classes2.dex", false).getDexFile());
    Assert.assertEquals(dexFile2, testFinder.findEntry(":classes2.dex", false).getDexFile());
    Assert.assertEquals(dexFile2, testFinder.findEntry("classes2.dex", false).getDexFile());
    assertEntryNotFound(testFinder, "ystem/framework/framework.jar:classes2.dex", false);
    assertEntryNotFound(testFinder, "ramework.jar:classes2.dex", false);
    assertEntryNotFound(testFinder, "lasses2.dex", false);
    assertEntryNotFound(testFinder, "classes2", false);
}
Also used : DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) DexEntryFinder(org.jf.dexlib2.DexFileFactory.DexEntryFinder) Test(org.junit.Test)

Example 32 with DexBackedDexFile

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

the class SmaliTestUtils method compileSmali.

public static DexBackedClassDef compileSmali(String smaliText, int apiLevel) throws RecognitionException, IOException {
    CommonTokenStream tokens;
    LexerErrorInterface lexer;
    DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(apiLevel));
    Reader reader = new StringReader(smaliText);
    lexer = new smaliFlexLexer(reader, apiLevel);
    tokens = new CommonTokenStream((TokenSource) lexer);
    smaliParser parser = new smaliParser(tokens);
    parser.setVerboseErrors(true);
    parser.setAllowOdex(false);
    parser.setApiLevel(apiLevel);
    smaliParser.smali_file_return result = parser.smali_file();
    if (parser.getNumberOfSyntaxErrors() > 0 || lexer.getNumberOfSyntaxErrors() > 0) {
        throw new RuntimeException("Error occurred while compiling text");
    }
    CommonTree t = result.getTree();
    CommonTreeNodeStream treeStream = new CommonTreeNodeStream(t);
    treeStream.setTokenStream(tokens);
    smaliTreeWalker dexGen = new smaliTreeWalker(treeStream);
    dexGen.setApiLevel(apiLevel);
    dexGen.setVerboseErrors(true);
    dexGen.setDexBuilder(dexBuilder);
    dexGen.smali_file();
    if (dexGen.getNumberOfSyntaxErrors() > 0) {
        throw new RuntimeException("Error occurred while compiling text");
    }
    MemoryDataStore dataStore = new MemoryDataStore();
    dexBuilder.writeTo(dataStore);
    DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.forApi(apiLevel), dataStore.getBuffer());
    return Iterables.getFirst(dexFile.getClasses(), null);
}
Also used : CommonTokenStream(org.antlr.runtime.CommonTokenStream) TokenSource(org.antlr.runtime.TokenSource) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) CommonTree(org.antlr.runtime.tree.CommonTree) MemoryDataStore(org.jf.dexlib2.writer.io.MemoryDataStore) Reader(java.io.Reader) StringReader(java.io.StringReader) DexBuilder(org.jf.dexlib2.writer.builder.DexBuilder) StringReader(java.io.StringReader) CommonTreeNodeStream(org.antlr.runtime.tree.CommonTreeNodeStream)

Example 33 with DexBackedDexFile

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

the class AnalysisArguments method loadClassPathForDexFile.

@Nonnull
public ClassPath loadClassPathForDexFile(@Nonnull File dexFileDir, @Nonnull MultiDexContainer.DexEntry<? extends DexBackedDexFile> dexEntry, boolean checkPackagePrivateAccess, int oatVersion) throws IOException {
    ClassPathResolver resolver;
    MultiDexContainer<? extends DexBackedDexFile> container = dexEntry.getContainer();
    if (oatVersion == NOT_SPECIFIED) {
        if (container instanceof OatFile) {
            checkPackagePrivateAccess = true;
            oatVersion = ((OatFile) container).getOatVersion();
        } else {
            oatVersion = VersionMap.mapApiToArtVersion(dexEntry.getDexFile().getOpcodes().api);
        }
    } else {
        // this should always be true for ART
        checkPackagePrivateAccess = true;
    }
    if (classPathDirectories == null || classPathDirectories.size() == 0) {
        classPathDirectories = Lists.newArrayList(dexFileDir.getPath());
    }
    List<String> filteredClassPathDirectories = Lists.newArrayList();
    if (classPathDirectories != null) {
        for (String dir : classPathDirectories) {
            File file = new File(dir);
            if (!file.exists()) {
                System.err.println(String.format("Warning: directory %s does not exist. Ignoring.", dir));
            } else if (!file.isDirectory()) {
                System.err.println(String.format("Warning: %s is not a directory. Ignoring.", dir));
            } else {
                filteredClassPathDirectories.add(dir);
            }
        }
    }
    if (bootClassPath == null) {
        // TODO: we should be able to get the api from the Opcodes object associated with the dexFile..
        // except that the oat version -> api mapping doesn't fully work yet
        resolver = new ClassPathResolver(filteredClassPathDirectories, classPath, dexEntry);
    } else if (bootClassPath.size() == 1 && bootClassPath.get(0).length() == 0) {
        // --bootclasspath "" is a special case, denoting that no bootclasspath should be used
        resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), classPath, dexEntry);
    } else {
        resolver = new ClassPathResolver(filteredClassPathDirectories, bootClassPath, classPath, dexEntry);
    }
    if (oatVersion == 0 && container instanceof OatFile) {
        oatVersion = ((OatFile) container).getOatVersion();
    }
    return new ClassPath(resolver.getResolvedClassProviders(), checkPackagePrivateAccess, oatVersion);
}
Also used : ClassPath(org.jf.dexlib2.analysis.ClassPath) ClassPathResolver(org.jf.dexlib2.analysis.ClassPathResolver) OatFile(org.jf.dexlib2.dexbacked.OatFile) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) OatFile(org.jf.dexlib2.dexbacked.OatFile) File(java.io.File) Nonnull(javax.annotation.Nonnull)

Example 34 with DexBackedDexFile

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

the class DexBackedInstruction method readFrom.

@Nonnull
public static Instruction readFrom(DexBackedDexFile dexFile, @Nonnull DexReader reader) {
    int opcodeValue = reader.peekUbyte();
    if (opcodeValue == 0) {
        opcodeValue = reader.peekUshort();
    }
    Opcode opcode = dexFile.getOpcodes().getOpcodeByValue(opcodeValue);
    Instruction instruction = buildInstruction(dexFile, opcode, reader.getOffset() + reader.dexBuf.getBaseOffset() - dexFile.getBuffer().getBaseOffset() - dexFile.getBaseDataOffset());
    reader.moveRelative(instruction.getCodeUnits() * 2);
    return instruction;
}
Also used : Opcode(org.jf.dexlib2.Opcode) Instruction(org.jf.dexlib2.iface.instruction.Instruction) Nonnull(javax.annotation.Nonnull)

Example 35 with DexBackedDexFile

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

the class ClassDataItem method makeAnnotator.

@Nonnull
public static SectionAnnotator makeAnnotator(@Nonnull DexAnnotator annotator, @Nonnull MapItem mapItem) {
    return new SectionAnnotator(annotator, mapItem) {

        private SectionAnnotator codeItemAnnotator = null;

        @Override
        public void annotateSection(@Nonnull AnnotatedBytes out) {
            codeItemAnnotator = annotator.getAnnotator(ItemType.CODE_ITEM);
            super.annotateSection(out);
        }

        @Nonnull
        @Override
        public String getItemName() {
            return "class_data_item";
        }

        @Override
        protected void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
            DexReader reader = dexFile.getBuffer().readerAt(out.getCursor());
            int staticFieldsSize = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "static_fields_size = %d", staticFieldsSize);
            int instanceFieldsSize = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "instance_fields_size = %d", instanceFieldsSize);
            int directMethodsSize = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "direct_methods_size = %d", directMethodsSize);
            int virtualMethodsSize = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "virtual_methods_size = %d", virtualMethodsSize);
            int previousIndex = 0;
            if (staticFieldsSize > 0) {
                out.annotate(0, "static_fields:");
                out.indent();
                for (int i = 0; i < staticFieldsSize; i++) {
                    out.annotate(0, "static_field[%d]", i);
                    out.indent();
                    previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex);
                    out.deindent();
                }
                out.deindent();
            }
            if (instanceFieldsSize > 0) {
                out.annotate(0, "instance_fields:");
                out.indent();
                previousIndex = 0;
                for (int i = 0; i < instanceFieldsSize; i++) {
                    out.annotate(0, "instance_field[%d]", i);
                    out.indent();
                    previousIndex = annotateEncodedField(out, dexFile, reader, previousIndex);
                    out.deindent();
                }
                out.deindent();
            }
            if (directMethodsSize > 0) {
                out.annotate(0, "direct_methods:");
                out.indent();
                previousIndex = 0;
                for (int i = 0; i < directMethodsSize; i++) {
                    out.annotate(0, "direct_method[%d]", i);
                    out.indent();
                    previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex);
                    out.deindent();
                }
                out.deindent();
            }
            if (virtualMethodsSize > 0) {
                out.annotate(0, "virtual_methods:");
                out.indent();
                previousIndex = 0;
                for (int i = 0; i < virtualMethodsSize; i++) {
                    out.annotate(0, "virtual_method[%d]", i);
                    out.indent();
                    previousIndex = annotateEncodedMethod(out, dexFile, reader, previousIndex);
                    out.deindent();
                }
                out.deindent();
            }
        }

        private int annotateEncodedField(@Nonnull AnnotatedBytes out, @Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int previousIndex) {
            // large values may be used for the index delta, which cause the cumulative index to overflow upon
            // addition, effectively allowing out of order entries.
            int indexDelta = reader.readLargeUleb128();
            int fieldIndex = previousIndex + indexDelta;
            out.annotateTo(reader.getOffset(), "field_idx_diff = %d: %s", indexDelta, FieldIdItem.getReferenceAnnotation(dexFile, fieldIndex));
            int accessFlags = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, Joiner.on('|').join(AccessFlags.getAccessFlagsForField(accessFlags)));
            return fieldIndex;
        }

        private int annotateEncodedMethod(@Nonnull AnnotatedBytes out, @Nonnull DexBackedDexFile dexFile, @Nonnull DexReader reader, int previousIndex) {
            // large values may be used for the index delta, which cause the cumulative index to overflow upon
            // addition, effectively allowing out of order entries.
            int indexDelta = reader.readLargeUleb128();
            int methodIndex = previousIndex + indexDelta;
            out.annotateTo(reader.getOffset(), "method_idx_diff = %d: %s", indexDelta, MethodIdItem.getReferenceAnnotation(dexFile, methodIndex));
            int accessFlags = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "access_flags = 0x%x: %s", accessFlags, Joiner.on('|').join(AccessFlags.getAccessFlagsForMethod(accessFlags)));
            int codeOffset = reader.readSmallUleb128();
            if (codeOffset == 0) {
                out.annotateTo(reader.getOffset(), "code_off = code_item[NO_OFFSET]");
            } else {
                out.annotateTo(reader.getOffset(), "code_off = code_item[0x%x]", codeOffset);
                addCodeItemIdentity(codeOffset, MethodIdItem.asString(dexFile, methodIndex));
            }
            return methodIndex;
        }

        private void addCodeItemIdentity(int codeItemOffset, String methodString) {
            if (codeItemAnnotator != null) {
                codeItemAnnotator.setItemIdentity(codeItemOffset, methodString);
            }
        }
    };
}
Also used : DexReader(org.jf.dexlib2.dexbacked.DexReader) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) Nonnull(javax.annotation.Nonnull) AnnotatedBytes(org.jf.dexlib2.util.AnnotatedBytes) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

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