Search in sources :

Example 6 with IndentingWriter

use of org.jf.util.IndentingWriter in project atlas by alibaba.

the class SmaliCodeUtils method methodImplementionToCode.

/**
     * 将方法的实现转换为smali代码
     *
     * @param dexBackedMethodImplementation
     * @param withLineNo                    是否包含行号
     * @return
     */
public static String methodImplementionToCode(DexBackedMethodImplementation dexBackedMethodImplementation, boolean withLineNo) {
    if (null == dexBackedMethodImplementation) {
        return null;
    }
    StringWriter stringWriter = new StringWriter();
    IndentingWriter writer = new IndentingWriter(stringWriter);
    MethodDefinition methodDefinition = new MethodDefinition(toClassDefinition(dexBackedMethodImplementation), dexBackedMethodImplementation.method, dexBackedMethodImplementation);
    try {
        methodDefinition.writeTo(writer);
    } catch (IOException e) {
        throw new RuntimeException(e.getMessage(), e);
    }
    if (withLineNo) {
        return stringWriter.toString();
    } else {
        List<String> codes = Lists.newArrayList();
        String[] lines = StringUtils.split(stringWriter.toString(), "\n");
        for (String line : lines) {
            if (StringUtils.isNoneBlank(line) && !line.matches("\\s+\\.line\\s+[0-9]+$")) {
                codes.add(line);
            }
        }
        return StringUtils.join(codes, "\n");
    }
}
Also used : StringWriter(java.io.StringWriter) MethodDefinition(org.jf.baksmali.Adaptors.MethodDefinition) IndentingWriter(org.jf.util.IndentingWriter) IOException(java.io.IOException)

Example 7 with IndentingWriter

use of org.jf.util.IndentingWriter in project smali by JesusFreke.

the class Baksmali method disassembleClass.

private static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler, BaksmaliOptions options) {
    /**
         * The path for the disassembly file is based on the package name
         * The class descriptor will look something like:
         * Ljava/lang/Object;
         * Where the there is leading 'L' and a trailing ';', and the parts of the
         * package name are separated by '/'
         */
    String classDescriptor = classDef.getType();
    //validate that the descriptor is formatted like we expect
    if (classDescriptor.charAt(0) != 'L' || classDescriptor.charAt(classDescriptor.length() - 1) != ';') {
        System.err.println("Unrecognized class descriptor - " + classDescriptor + " - skipping class");
        return false;
    }
    File smaliFile = fileNameHandler.getUniqueFilenameForClass(classDescriptor);
    //create and initialize the top level string template
    ClassDefinition classDefinition = new ClassDefinition(options, classDef);
    //write the disassembly
    Writer writer = null;
    try {
        File smaliParent = smaliFile.getParentFile();
        if (!smaliParent.exists()) {
            if (!smaliParent.mkdirs()) {
                // check again, it's likely it was created in a different thread
                if (!smaliParent.exists()) {
                    System.err.println("Unable to create directory " + smaliParent.toString() + " - skipping class");
                    return false;
                }
            }
        }
        if (!smaliFile.exists()) {
            if (!smaliFile.createNewFile()) {
                System.err.println("Unable to create file " + smaliFile.toString() + " - skipping class");
                return false;
            }
        }
        BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(smaliFile), "UTF8"));
        writer = new IndentingWriter(bufWriter);
        classDefinition.writeTo((IndentingWriter) writer);
    } catch (Exception ex) {
        System.err.println("\n\nError occurred while disassembling class " + classDescriptor.replace('/', '.') + " - skipping class");
        ex.printStackTrace();
        // noinspection ResultOfMethodCallIgnored
        smaliFile.delete();
        return false;
    } finally {
        if (writer != null) {
            try {
                writer.close();
            } catch (Throwable ex) {
                System.err.println("\n\nError occurred while closing file " + smaliFile.toString());
                ex.printStackTrace();
            }
        }
    }
    return true;
}
Also used : IndentingWriter(org.jf.util.IndentingWriter) ClassDefinition(org.jf.baksmali.Adaptors.ClassDefinition) DexFile(org.jf.dexlib2.iface.DexFile) IndentingWriter(org.jf.util.IndentingWriter)

Example 8 with IndentingWriter

use of org.jf.util.IndentingWriter in project smali by JesusFreke.

the class MethodDefinition method addInstructionMethodItems.

private void addInstructionMethodItems(List<MethodItem> methodItems) {
    int currentCodeAddress = 0;
    for (int i = 0; i < effectiveInstructions.size(); i++) {
        Instruction instruction = effectiveInstructions.get(i);
        MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction);
        methodItems.add(methodItem);
        if (i != effectiveInstructions.size() - 1) {
            methodItems.add(new BlankMethodItem(currentCodeAddress));
        }
        if (classDef.options.codeOffsets) {
            methodItems.add(new MethodItem(currentCodeAddress) {

                @Override
                public double getSortOrder() {
                    return -1000;
                }

                @Override
                public boolean writeTo(IndentingWriter writer) throws IOException {
                    writer.write("#@");
                    writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
                    return true;
                }
            });
        }
        if (classDef.options.accessorComments && classDef.options.syntheticAccessorResolver != null && (instruction instanceof ReferenceInstruction)) {
            Opcode opcode = instruction.getOpcode();
            if (opcode.referenceType == ReferenceType.METHOD) {
                MethodReference methodReference = null;
                try {
                    methodReference = (MethodReference) ((ReferenceInstruction) instruction).getReference();
                } catch (InvalidItemIndex ex) {
                // just ignore it for now. We'll deal with it later, when processing the instructions
                // themselves
                }
                if (methodReference != null && SyntheticAccessorResolver.looksLikeSyntheticAccessor(methodReference.getName())) {
                    AccessedMember accessedMember = classDef.options.syntheticAccessorResolver.getAccessedMember(methodReference);
                    if (accessedMember != null) {
                        methodItems.add(new SyntheticAccessCommentMethodItem(accessedMember, currentCodeAddress));
                    }
                }
            }
        }
        currentCodeAddress += instruction.getCodeUnits();
    }
}
Also used : DebugMethodItem(org.jf.baksmali.Adaptors.Debug.DebugMethodItem) InvalidItemIndex(org.jf.dexlib2.dexbacked.DexBackedDexFile.InvalidItemIndex) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) Opcode(org.jf.dexlib2.Opcode) IOException(java.io.IOException) OffsetInstruction(org.jf.dexlib2.iface.instruction.OffsetInstruction) AnalyzedInstruction(org.jf.dexlib2.analysis.AnalyzedInstruction) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ReferenceInstruction(org.jf.dexlib2.iface.instruction.ReferenceInstruction) AccessedMember(org.jf.dexlib2.util.SyntheticAccessorResolver.AccessedMember) IndentingWriter(org.jf.util.IndentingWriter) MethodReference(org.jf.dexlib2.iface.reference.MethodReference)

Example 9 with IndentingWriter

use of org.jf.util.IndentingWriter in project smali by JesusFreke.

the class MethodDefinition method addAnalyzedInstructionMethodItems.

private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method, classDef.options.inlineResolver, classDef.options.normalizeVirtualMethods);
    AnalysisException analysisException = methodAnalyzer.getAnalysisException();
    if (analysisException != null) {
        // TODO: need to keep track of whether any errors occurred, so we can exit with a non-zero result
        methodItems.add(new CommentMethodItem(String.format("AnalysisException: %s", analysisException.getMessage()), analysisException.codeAddress, Integer.MIN_VALUE));
        analysisException.printStackTrace(System.err);
    }
    List<AnalyzedInstruction> instructions = methodAnalyzer.getAnalyzedInstructions();
    int currentCodeAddress = 0;
    for (int i = 0; i < instructions.size(); i++) {
        AnalyzedInstruction instruction = instructions.get(i);
        MethodItem methodItem = InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction.getInstruction());
        methodItems.add(methodItem);
        if (instruction.getInstruction().getOpcode().format == Format.UnresolvedOdexInstruction) {
            methodItems.add(new CommentedOutMethodItem(InstructionMethodItemFactory.makeInstructionFormatMethodItem(this, currentCodeAddress, instruction.getOriginalInstruction())));
        }
        if (i != instructions.size() - 1) {
            methodItems.add(new BlankMethodItem(currentCodeAddress));
        }
        if (classDef.options.codeOffsets) {
            methodItems.add(new MethodItem(currentCodeAddress) {

                @Override
                public double getSortOrder() {
                    return -1000;
                }

                @Override
                public boolean writeTo(IndentingWriter writer) throws IOException {
                    writer.write("#@");
                    writer.printUnsignedLongAsHex(codeAddress & 0xFFFFFFFFL);
                    return true;
                }
            });
        }
        if (classDef.options.registerInfo != 0 && !instruction.getInstruction().getOpcode().format.isPayloadFormat) {
            methodItems.add(new PreInstructionRegisterInfoMethodItem(classDef.options.registerInfo, methodAnalyzer, registerFormatter, instruction, currentCodeAddress));
            methodItems.add(new PostInstructionRegisterInfoMethodItem(registerFormatter, instruction, currentCodeAddress));
        }
        currentCodeAddress += instruction.getInstruction().getCodeUnits();
    }
}
Also used : DebugMethodItem(org.jf.baksmali.Adaptors.Debug.DebugMethodItem) MethodAnalyzer(org.jf.dexlib2.analysis.MethodAnalyzer) IOException(java.io.IOException) AnalyzedInstruction(org.jf.dexlib2.analysis.AnalyzedInstruction) AnalysisException(org.jf.dexlib2.analysis.AnalysisException) IndentingWriter(org.jf.util.IndentingWriter)

Example 10 with IndentingWriter

use of org.jf.util.IndentingWriter in project smali by JesusFreke.

the class BaksmaliTestUtils method getNormalizedSmali.

@Nonnull
public static String getNormalizedSmali(@Nonnull ClassDef classDef, @Nonnull BaksmaliOptions options, boolean stripComments) throws IOException {
    StringWriter stringWriter = new StringWriter();
    IndentingWriter writer = new IndentingWriter(stringWriter);
    ClassDefinition classDefinition = new ClassDefinition(options, classDef);
    classDefinition.writeTo(writer);
    writer.close();
    return normalizeSmali(stringWriter.toString(), stripComments);
}
Also used : StringWriter(java.io.StringWriter) IndentingWriter(org.jf.util.IndentingWriter) ClassDefinition(org.jf.baksmali.Adaptors.ClassDefinition) Nonnull(javax.annotation.Nonnull)

Aggregations

IndentingWriter (org.jf.util.IndentingWriter)20 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)8 IOException (java.io.IOException)5 ClassDefinition (org.jf.baksmali.Adaptors.ClassDefinition)5 HashSet (java.util.HashSet)4 AnalyzedInstruction (org.jf.dexlib2.analysis.AnalyzedInstruction)4 StringWriter (java.io.StringWriter)3 DexFile (org.jf.dexlib2.iface.DexFile)3 MethodReplaceAnnotation (com.taobao.android.apatch.annotation.MethodReplaceAnnotation)2 ClassDefinition (com.taobao.android.baksmali.adaptors.ClassDefinition)2 DebugMethodItem (com.taobao.android.baksmali.adaptors.Debug.DebugMethodItem)2 EndPrologueMethodItem (com.taobao.android.baksmali.adaptors.Debug.EndPrologueMethodItem)2 BufferedWriter (java.io.BufferedWriter)2 File (java.io.File)2 FileOutputStream (java.io.FileOutputStream)2 OutputStreamWriter (java.io.OutputStreamWriter)2 DebugMethodItem (org.jf.baksmali.Adaptors.Debug.DebugMethodItem)2 Opcode (org.jf.dexlib2.Opcode)2 AnalysisException (org.jf.dexlib2.analysis.AnalysisException)2 MethodAnalyzer (org.jf.dexlib2.analysis.MethodAnalyzer)2