Search in sources :

Example 21 with DexFile

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

the class CodeItem method makeAnnotator.

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

        private SectionAnnotator debugInfoAnnotator = null;

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

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

        @Override
        public int getItemAlignment() {
            return 4;
        }

        @Override
        public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
            try {
                DexReader reader = dexFile.readerAt(out.getCursor());
                int registers = reader.readUshort();
                out.annotate(2, "registers_size = %d", registers);
                int inSize = reader.readUshort();
                out.annotate(2, "ins_size = %d", inSize);
                int outSize = reader.readUshort();
                out.annotate(2, "outs_size = %d", outSize);
                int triesCount = reader.readUshort();
                out.annotate(2, "tries_size = %d", triesCount);
                int debugInfoOffset = reader.readInt();
                out.annotate(4, "debug_info_off = 0x%x", debugInfoOffset);
                if (debugInfoOffset > 0) {
                    addDebugInfoIdentity(debugInfoOffset, itemIdentity);
                }
                int instructionSize = reader.readSmallUint();
                out.annotate(4, "insns_size = 0x%x", instructionSize);
                out.annotate(0, "instructions:");
                out.indent();
                out.setLimit(out.getCursor(), out.getCursor() + instructionSize * 2);
                int end = reader.getOffset() + instructionSize * 2;
                try {
                    while (reader.getOffset() < end) {
                        Instruction instruction = DexBackedInstruction.readFrom(reader);
                        // if we read past the end of the instruction list
                        if (reader.getOffset() > end) {
                            out.annotateTo(end, "truncated instruction");
                            reader.setOffset(end);
                        } else {
                            switch(instruction.getOpcode().format) {
                                case Format10x:
                                    annotateInstruction10x(out, instruction);
                                    break;
                                case Format35c:
                                    annotateInstruction35c(out, (Instruction35c) instruction);
                                    break;
                                case Format3rc:
                                    annotateInstruction3rc(out, (Instruction3rc) instruction);
                                    break;
                                case ArrayPayload:
                                    annotateArrayPayload(out, (ArrayPayload) instruction);
                                    break;
                                case PackedSwitchPayload:
                                    annotatePackedSwitchPayload(out, (PackedSwitchPayload) instruction);
                                    break;
                                case SparseSwitchPayload:
                                    annotateSparseSwitchPayload(out, (SparseSwitchPayload) instruction);
                                    break;
                                default:
                                    annotateDefaultInstruction(out, instruction);
                                    break;
                            }
                        }
                        assert reader.getOffset() == out.getCursor();
                    }
                } catch (ExceptionWithContext ex) {
                    ex.printStackTrace(System.err);
                    out.annotate(0, "annotation error: %s", ex.getMessage());
                    out.moveTo(end);
                    reader.setOffset(end);
                } finally {
                    out.clearLimit();
                    out.deindent();
                }
                if (triesCount > 0) {
                    if ((reader.getOffset() % 4) != 0) {
                        reader.readUshort();
                        out.annotate(2, "padding");
                    }
                    out.annotate(0, "try_items:");
                    out.indent();
                    try {
                        for (int i = 0; i < triesCount; i++) {
                            out.annotate(0, "try_item[%d]:", i);
                            out.indent();
                            try {
                                int startAddr = reader.readSmallUint();
                                out.annotate(4, "start_addr = 0x%x", startAddr);
                                int instructionCount = reader.readUshort();
                                out.annotate(2, "insn_count = 0x%x", instructionCount);
                                int handlerOffset = reader.readUshort();
                                out.annotate(2, "handler_off = 0x%x", handlerOffset);
                            } finally {
                                out.deindent();
                            }
                        }
                    } finally {
                        out.deindent();
                    }
                    int handlerListCount = reader.readSmallUleb128();
                    out.annotate(0, "encoded_catch_handler_list:");
                    out.annotateTo(reader.getOffset(), "size = %d", handlerListCount);
                    out.indent();
                    try {
                        for (int i = 0; i < handlerListCount; i++) {
                            out.annotate(0, "encoded_catch_handler[%d]", i);
                            out.indent();
                            try {
                                int handlerCount = reader.readSleb128();
                                out.annotateTo(reader.getOffset(), "size = %d", handlerCount);
                                boolean hasCatchAll = handlerCount <= 0;
                                handlerCount = Math.abs(handlerCount);
                                if (handlerCount != 0) {
                                    out.annotate(0, "handlers:");
                                    out.indent();
                                    try {
                                        for (int j = 0; j < handlerCount; j++) {
                                            out.annotate(0, "encoded_type_addr_pair[%d]", i);
                                            out.indent();
                                            try {
                                                int typeIndex = reader.readSmallUleb128();
                                                out.annotateTo(reader.getOffset(), TypeIdItem.getReferenceAnnotation(dexFile, typeIndex));
                                                int handlerAddress = reader.readSmallUleb128();
                                                out.annotateTo(reader.getOffset(), "addr = 0x%x", handlerAddress);
                                            } finally {
                                                out.deindent();
                                            }
                                        }
                                    } finally {
                                        out.deindent();
                                    }
                                }
                                if (hasCatchAll) {
                                    int catchAllAddress = reader.readSmallUleb128();
                                    out.annotateTo(reader.getOffset(), "catch_all_addr = 0x%x", catchAllAddress);
                                }
                            } finally {
                                out.deindent();
                            }
                        }
                    } finally {
                        out.deindent();
                    }
                }
            } catch (ExceptionWithContext ex) {
                out.annotate(0, "annotation error: %s", ex.getMessage());
            }
        }

        private String formatRegister(int registerNum) {
            return String.format("v%d", registerNum);
        }

        private void annotateInstruction10x(@Nonnull AnnotatedBytes out, @Nonnull Instruction instruction) {
            out.annotate(2, instruction.getOpcode().name);
        }

        private void annotateInstruction35c(@Nonnull AnnotatedBytes out, @Nonnull Instruction35c instruction) {
            List<String> args = Lists.newArrayList();
            int registerCount = instruction.getRegisterCount();
            if (registerCount == 1) {
                args.add(formatRegister(instruction.getRegisterC()));
            } else if (registerCount == 2) {
                args.add(formatRegister(instruction.getRegisterC()));
                args.add(formatRegister(instruction.getRegisterD()));
            } else if (registerCount == 3) {
                args.add(formatRegister(instruction.getRegisterC()));
                args.add(formatRegister(instruction.getRegisterD()));
                args.add(formatRegister(instruction.getRegisterE()));
            } else if (registerCount == 4) {
                args.add(formatRegister(instruction.getRegisterC()));
                args.add(formatRegister(instruction.getRegisterD()));
                args.add(formatRegister(instruction.getRegisterE()));
                args.add(formatRegister(instruction.getRegisterF()));
            } else if (registerCount == 5) {
                args.add(formatRegister(instruction.getRegisterC()));
                args.add(formatRegister(instruction.getRegisterD()));
                args.add(formatRegister(instruction.getRegisterE()));
                args.add(formatRegister(instruction.getRegisterF()));
                args.add(formatRegister(instruction.getRegisterG()));
            }
            String reference = ReferenceUtil.getReferenceString(instruction.getReference());
            out.annotate(6, String.format("%s {%s}, %s", instruction.getOpcode().name, Joiner.on(", ").join(args), reference));
        }

        private void annotateInstruction3rc(@Nonnull AnnotatedBytes out, @Nonnull Instruction3rc instruction) {
            int startRegister = instruction.getStartRegister();
            int endRegister = startRegister + instruction.getRegisterCount() - 1;
            String reference = ReferenceUtil.getReferenceString(instruction.getReference());
            out.annotate(6, String.format("%s {%s .. %s}, %s", instruction.getOpcode().name, formatRegister(startRegister), formatRegister(endRegister), reference));
        }

        private void annotateDefaultInstruction(@Nonnull AnnotatedBytes out, @Nonnull Instruction instruction) {
            List<String> args = Lists.newArrayList();
            if (instruction instanceof OneRegisterInstruction) {
                args.add(formatRegister(((OneRegisterInstruction) instruction).getRegisterA()));
                if (instruction instanceof TwoRegisterInstruction) {
                    args.add(formatRegister(((TwoRegisterInstruction) instruction).getRegisterB()));
                    if (instruction instanceof ThreeRegisterInstruction) {
                        args.add(formatRegister(((ThreeRegisterInstruction) instruction).getRegisterC()));
                    }
                }
            } else if (instruction instanceof VerificationErrorInstruction) {
                String verificationError = VerificationError.getVerificationErrorName(((VerificationErrorInstruction) instruction).getVerificationError());
                if (verificationError != null) {
                    args.add(verificationError);
                } else {
                    args.add("invalid verification error type");
                }
            }
            if (instruction instanceof ReferenceInstruction) {
                args.add(ReferenceUtil.getReferenceString(((ReferenceInstruction) instruction).getReference()));
            } else if (instruction instanceof OffsetInstruction) {
                int offset = ((OffsetInstruction) instruction).getCodeOffset();
                String sign = offset >= 0 ? "+" : "-";
                args.add(String.format("%s0x%x", sign, Math.abs(offset)));
            } else if (instruction instanceof NarrowLiteralInstruction) {
                int value = ((NarrowLiteralInstruction) instruction).getNarrowLiteral();
                if (NumberUtils.isLikelyFloat(value)) {
                    args.add(String.format("%d # %f", value, Float.intBitsToFloat(value)));
                } else {
                    args.add(String.format("%d", value));
                }
            } else if (instruction instanceof WideLiteralInstruction) {
                long value = ((WideLiteralInstruction) instruction).getWideLiteral();
                if (NumberUtils.isLikelyDouble(value)) {
                    args.add(String.format("%d # %f", value, Double.longBitsToDouble(value)));
                } else {
                    args.add(String.format("%d", value));
                }
            } else if (instruction instanceof FieldOffsetInstruction) {
                int fieldOffset = ((FieldOffsetInstruction) instruction).getFieldOffset();
                args.add(String.format("field@0x%x", fieldOffset));
            } else if (instruction instanceof VtableIndexInstruction) {
                int vtableIndex = ((VtableIndexInstruction) instruction).getVtableIndex();
                args.add(String.format("vtable@%d", vtableIndex));
            } else if (instruction instanceof InlineIndexInstruction) {
                int inlineIndex = ((InlineIndexInstruction) instruction).getInlineIndex();
                args.add(String.format("inline@%d", inlineIndex));
            }
            out.annotate(instruction.getCodeUnits() * 2, "%s %s", instruction.getOpcode().name, Joiner.on(", ").join(args));
        }

        private void annotateArrayPayload(@Nonnull AnnotatedBytes out, @Nonnull ArrayPayload instruction) {
            List<Number> elements = instruction.getArrayElements();
            int elementWidth = instruction.getElementWidth();
            out.annotate(2, instruction.getOpcode().name);
            out.indent();
            out.annotate(2, "element_width = %d", elementWidth);
            out.annotate(4, "size = %d", elements.size());
            out.annotate(0, "elements:");
            out.indent();
            for (int i = 0; i < elements.size(); i++) {
                if (elementWidth == 8) {
                    long value = elements.get(i).longValue();
                    if (NumberUtils.isLikelyDouble(value)) {
                        out.annotate(elementWidth, "element[%d] = %d # %f", i, value, Double.longBitsToDouble(value));
                    } else {
                        out.annotate(elementWidth, "element[%d] = %d", i, value);
                    }
                } else {
                    int value = elements.get(i).intValue();
                    if (NumberUtils.isLikelyFloat(value)) {
                        out.annotate(elementWidth, "element[%d] = %d # %f", i, value, Float.intBitsToFloat(value));
                    } else {
                        out.annotate(elementWidth, "element[%d] = %d", i, value);
                    }
                }
            }
            if (out.getCursor() % 2 != 0) {
                out.annotate(1, "padding");
            }
            out.deindent();
            out.deindent();
        }

        private void annotatePackedSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull PackedSwitchPayload instruction) {
            List<? extends SwitchElement> elements = instruction.getSwitchElements();
            out.annotate(2, instruction.getOpcode().name);
            out.indent();
            out.annotate(2, "size = %d", elements.size());
            if (elements.size() == 0) {
                out.annotate(4, "first_key");
            } else {
                out.annotate(4, "first_key = %d", elements.get(0).getKey());
                out.annotate(0, "targets:");
                out.indent();
                for (int i = 0; i < elements.size(); i++) {
                    out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset());
                }
                out.deindent();
            }
            out.deindent();
        }

        private void annotateSparseSwitchPayload(@Nonnull AnnotatedBytes out, @Nonnull SparseSwitchPayload instruction) {
            List<? extends SwitchElement> elements = instruction.getSwitchElements();
            out.annotate(2, instruction.getOpcode().name);
            out.indent();
            out.annotate(2, "size = %d", elements.size());
            if (elements.size() > 0) {
                out.annotate(0, "keys:");
                out.indent();
                for (int i = 0; i < elements.size(); i++) {
                    out.annotate(4, "key[%d] = %d", i, elements.get(i).getKey());
                }
                out.deindent();
                out.annotate(0, "targets:");
                out.indent();
                for (int i = 0; i < elements.size(); i++) {
                    out.annotate(4, "target[%d] = %d", i, elements.get(i).getOffset());
                }
                out.deindent();
            }
            out.deindent();
        }

        private void addDebugInfoIdentity(int debugInfoOffset, String methodString) {
            if (debugInfoAnnotator != null) {
                debugInfoAnnotator.setItemIdentity(debugInfoOffset, methodString);
            }
        }
    };
}
Also used : DexReader(org.jf.dexlib2.dexbacked.DexReader) DexBackedInstruction(org.jf.dexlib2.dexbacked.instruction.DexBackedInstruction) ExceptionWithContext(org.jf.util.ExceptionWithContext) Nonnull(javax.annotation.Nonnull) AnnotatedBytes(org.jf.dexlib2.util.AnnotatedBytes) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Example 22 with DexFile

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

the class DebugInfoItem method makeAnnotator.

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

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

        @Override
        public void annotateItem(@Nonnull AnnotatedBytes out, int itemIndex, @Nullable String itemIdentity) {
            DexReader reader = dexFile.readerAt(out.getCursor());
            int lineStart = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "line_start = %d", lineStart);
            int parametersSize = reader.readSmallUleb128();
            out.annotateTo(reader.getOffset(), "parameters_size = %d", parametersSize);
            if (parametersSize > 0) {
                out.annotate(0, "parameters:");
                out.indent();
                for (int i = 0; i < parametersSize; i++) {
                    int paramaterIndex = reader.readSmallUleb128() - 1;
                    out.annotateTo(reader.getOffset(), "%s", StringIdItem.getOptionalReferenceAnnotation(dexFile, paramaterIndex, true));
                }
                out.deindent();
            }
            out.annotate(0, "debug opcodes:");
            out.indent();
            int codeAddress = 0;
            int lineNumber = lineStart;
            loop: while (true) {
                int opcode = reader.readUbyte();
                switch(opcode) {
                    case DebugItemType.END_SEQUENCE:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_END_SEQUENCE");
                            break loop;
                        }
                    case DebugItemType.ADVANCE_PC:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_ADVANCE_PC");
                            out.indent();
                            int addressDiff = reader.readSmallUleb128();
                            codeAddress += addressDiff;
                            out.annotateTo(reader.getOffset(), "addr_diff = +0x%x: 0x%x", addressDiff, codeAddress);
                            out.deindent();
                            break;
                        }
                    case DebugItemType.ADVANCE_LINE:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_ADVANCE_LINE");
                            out.indent();
                            int lineDiff = reader.readSleb128();
                            lineNumber += lineDiff;
                            out.annotateTo(reader.getOffset(), "line_diff = +%d: %d", Math.abs(lineDiff), lineNumber);
                            out.deindent();
                            break;
                        }
                    case DebugItemType.START_LOCAL:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_START_LOCAL");
                            out.indent();
                            int registerNum = reader.readSmallUleb128();
                            out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
                            int nameIndex = reader.readSmallUleb128() - 1;
                            out.annotateTo(reader.getOffset(), "name_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true));
                            int typeIndex = reader.readSmallUleb128() - 1;
                            out.annotateTo(reader.getOffset(), "type_idx = %s", TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex));
                            out.deindent();
                            break;
                        }
                    case DebugItemType.START_LOCAL_EXTENDED:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_START_LOCAL_EXTENDED");
                            out.indent();
                            int registerNum = reader.readSmallUleb128();
                            out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
                            int nameIndex = reader.readSmallUleb128() - 1;
                            out.annotateTo(reader.getOffset(), "name_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIndex, true));
                            int typeIndex = reader.readSmallUleb128() - 1;
                            out.annotateTo(reader.getOffset(), "type_idx = %s", TypeIdItem.getOptionalReferenceAnnotation(dexFile, typeIndex));
                            int sigIndex = reader.readSmallUleb128() - 1;
                            out.annotateTo(reader.getOffset(), "sig_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, sigIndex, true));
                            out.deindent();
                            break;
                        }
                    case DebugItemType.END_LOCAL:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_END_LOCAL");
                            out.indent();
                            int registerNum = reader.readSmallUleb128();
                            out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
                            out.deindent();
                            break;
                        }
                    case DebugItemType.RESTART_LOCAL:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_RESTART_LOCAL");
                            out.indent();
                            int registerNum = reader.readSmallUleb128();
                            out.annotateTo(reader.getOffset(), "register_num = v%d", registerNum);
                            out.deindent();
                            break;
                        }
                    case DebugItemType.PROLOGUE_END:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_SET_PROLOGUE_END");
                            break;
                        }
                    case DebugItemType.EPILOGUE_BEGIN:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_SET_EPILOGUE_BEGIN");
                            break;
                        }
                    case DebugItemType.SET_SOURCE_FILE:
                        {
                            out.annotateTo(reader.getOffset(), "DBG_SET_FILE");
                            out.indent();
                            int nameIdx = reader.readSmallUleb128() - 1;
                            out.annotateTo(reader.getOffset(), "name_idx = %s", StringIdItem.getOptionalReferenceAnnotation(dexFile, nameIdx));
                            out.deindent();
                            break;
                        }
                    default:
                        int adjusted = opcode - 0x0A;
                        int addressDiff = adjusted / 15;
                        int lineDiff = (adjusted % 15) - 4;
                        codeAddress += addressDiff;
                        lineNumber += lineDiff;
                        out.annotateTo(reader.getOffset(), "address_diff = +0x%x:0x%x, line_diff = +%d:%d, ", addressDiff, codeAddress, lineDiff, lineNumber);
                        break;
                }
            }
            out.deindent();
        }
    };
}
Also used : DexReader(org.jf.dexlib2.dexbacked.DexReader) Nonnull(javax.annotation.Nonnull) AnnotatedBytes(org.jf.dexlib2.util.AnnotatedBytes) Nullable(javax.annotation.Nullable) Nonnull(javax.annotation.Nonnull)

Example 23 with DexFile

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

the class AnalysisArguments method loadClassPathForDexFile.

@Nonnull
public ClassPath loadClassPathForDexFile(@Nonnull File dexFileDir, @Nonnull DexFile dexFile, boolean checkPackagePrivateAccess, int oatVersion) throws IOException {
    ClassPathResolver resolver;
    // regardless of the actual version of the oat file
    if (oatVersion == NOT_ART) {
        if (dexFile instanceof OatDexFile) {
            checkPackagePrivateAccess = true;
            oatVersion = ((OatDexFile) dexFile).getContainer().getOatVersion();
        }
    } 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, dexFile);
    } 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, dexFile);
    } else {
        resolver = new ClassPathResolver(filteredClassPathDirectories, bootClassPath, classPath, dexFile);
    }
    if (oatVersion == 0 && dexFile instanceof OatDexFile) {
        oatVersion = ((OatDexFile) dexFile).getContainer().getOatVersion();
    }
    return new ClassPath(resolver.getResolvedClassProviders(), checkPackagePrivateAccess, oatVersion);
}
Also used : ClassPath(org.jf.dexlib2.analysis.ClassPath) ClassPathResolver(org.jf.dexlib2.analysis.ClassPathResolver) OatDexFile(org.jf.dexlib2.dexbacked.OatFile.OatDexFile) File(java.io.File) DexFile(org.jf.dexlib2.iface.DexFile) OatDexFile(org.jf.dexlib2.dexbacked.OatFile.OatDexFile) Nonnull(javax.annotation.Nonnull)

Example 24 with DexFile

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

the class DexInputCommand method loadDexFile.

/**
     * Parses a dex file input from the user and loads the given dex file.
     *
     * In some cases, the input file can contain multiple dex files. If this is the case, you can refer to a specific
     * dex file with a slash, followed by the entry name, optionally in quotes.
     *
     * If the entry name is enclosed in quotes, then it will strip the first and last quote and look for an entry with
     * exactly that name. Otherwise, it will perform a partial filename match against the entry to find any candidates.
     * If there is a single matching candidate, it will be used. Otherwise, an error will be generated.
     *
     * For example, to refer to the "/system/framework/framework.jar:classes2.dex" entry within the
     * "framework/arm/framework.oat" oat file, you could use any of:
     *
     * framework/arm/framework.oat/"/system/framework/framework.jar:classes2.dex"
     * framework/arm/framework.oat/system/framework/framework.jar:classes2.dex
     * framework/arm/framework.oat/framework/framework.jar:classes2.dex
     * framework/arm/framework.oat/framework.jar:classes2.dex
     * framework/arm/framework.oat/classes2.dex
     *
     * The last option is the easiest, but only works if the oat file doesn't contain another entry with the
     * "classes2.dex" name. e.g. "/system/framework/blah.jar:classes2.dex"
     *
     * It's technically possible (although unlikely) for an oat file to contain 2 entries like:
     * /system/framework/framework.jar:classes2.dex
     * system/framework/framework.jar:classes2.dex
     *
     * In this case, the "framework/arm/framework.oat/system/framework/framework.jar:classes2.dex" syntax will generate
     * an error because both entries match the partial entry name. Instead, you could use the following for the
     * first and second entry respectively:
     *
     * framework/arm/framework.oat/"/system/framework/framework.jar:classes2.dex"
     * framework/arm/framework.oat/"system/framework/framework.jar:classes2.dex"
     *
     * @param input The name of a dex, apk, odex or oat file/entry.
     */
protected void loadDexFile(@Nonnull String input) {
    File file = new File(input);
    while (file != null && !file.exists()) {
        file = file.getParentFile();
    }
    if (file == null || !file.exists() || file.isDirectory()) {
        System.err.println("Can't find file: " + input);
        System.exit(1);
    }
    inputFile = file;
    String dexEntry = null;
    if (file.getPath().length() < input.length()) {
        dexEntry = input.substring(file.getPath().length() + 1);
    }
    if (!Strings.isNullOrEmpty(dexEntry)) {
        boolean exactMatch = false;
        if (dexEntry.length() > 2 && dexEntry.charAt(0) == '"' && dexEntry.charAt(dexEntry.length() - 1) == '"') {
            dexEntry = dexEntry.substring(1, dexEntry.length() - 1);
            exactMatch = true;
        }
        inputEntry = dexEntry;
        try {
            dexFile = DexFileFactory.loadDexEntry(file, dexEntry, exactMatch, Opcodes.forApi(apiLevel));
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    } else {
        try {
            dexFile = DexFileFactory.loadDexFile(file, Opcodes.forApi(apiLevel));
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
    }
}
Also used : IOException(java.io.IOException) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File)

Example 25 with DexFile

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

the class DumpCommand method dump.

/**
     * Writes an annotated hex dump of the given dex file to output.
     *
     * @param dexFile The dex file to dump
     * @param output An OutputStream to write the annotated hex dump to. The caller is responsible for closing this
     *               when needed.
     *
     * @throws IOException
     */
public static void dump(@Nonnull DexBackedDexFile dexFile, @Nonnull OutputStream output) throws IOException {
    Writer writer = new BufferedWriter(new OutputStreamWriter(output));
    int consoleWidth = ConsoleUtil.getConsoleWidth();
    if (consoleWidth <= 0) {
        consoleWidth = 120;
    }
    RawDexFile rawDexFile = new RawDexFile(dexFile.getOpcodes(), dexFile);
    DexAnnotator annotator = new DexAnnotator(rawDexFile, consoleWidth);
    annotator.writeAnnotations(writer);
}
Also used : DexAnnotator(org.jf.dexlib2.dexbacked.raw.util.DexAnnotator) RawDexFile(org.jf.dexlib2.dexbacked.raw.RawDexFile)

Aggregations

DexFile (org.jf.dexlib2.iface.DexFile)28 ClassDef (org.jf.dexlib2.iface.ClassDef)26 Test (org.junit.Test)17 Nonnull (javax.annotation.Nonnull)15 DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)15 ImmutableClassDef (org.jf.dexlib2.immutable.ImmutableClassDef)13 File (java.io.File)12 ImmutableDexFile (org.jf.dexlib2.immutable.ImmutableDexFile)12 IOException (java.io.IOException)10 Method (org.jf.dexlib2.iface.Method)10 ImmutableMethod (org.jf.dexlib2.immutable.ImmutableMethod)10 MethodImplementation (org.jf.dexlib2.iface.MethodImplementation)8 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)8 MethodImplementationBuilder (org.jf.dexlib2.builder.MethodImplementationBuilder)7 BuilderInstruction10x (org.jf.dexlib2.builder.instruction.BuilderInstruction10x)7 BuilderInstruction21t (org.jf.dexlib2.builder.instruction.BuilderInstruction21t)6 BuilderInstruction22c (org.jf.dexlib2.builder.instruction.BuilderInstruction22c)6 Instruction (org.jf.dexlib2.iface.instruction.Instruction)6 ImmutableMethodParameter (org.jf.dexlib2.immutable.ImmutableMethodParameter)6 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)5