Search in sources :

Example 11 with IndentingWriter

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

the class ClassDefinition method writeDirectMethods.

private Set<String> writeDirectMethods(IndentingWriter writer) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenMethods = new HashSet<String>();
    Iterable<? extends Method> directMethods;
    if (classDef instanceof DexBackedClassDef) {
        directMethods = ((DexBackedClassDef) classDef).getDirectMethods(false);
    } else {
        directMethods = classDef.getDirectMethods();
    }
    for (Method method : directMethods) {
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# direct methods");
            wroteHeader = true;
        }
        writer.write('\n');
        // TODO: check for method validation errors
        String methodString = ReferenceUtil.getMethodDescriptor(method, true);
        IndentingWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = new CommentingIndentingWriter(writer);
        }
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.writeTo(methodWriter);
        }
    }
    return writtenMethods;
}
Also used : IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 12 with IndentingWriter

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

the class ClassDefinition method writeInstanceFields.

private void writeInstanceFields(IndentingWriter writer, Set<String> staticFields) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenFields = new HashSet<String>();
    Iterable<? extends Field> instanceFields;
    if (classDef instanceof DexBackedClassDef) {
        instanceFields = ((DexBackedClassDef) classDef).getInstanceFields(false);
    } else {
        instanceFields = classDef.getInstanceFields();
    }
    for (Field field : instanceFields) {
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# instance fields");
            wroteHeader = true;
        }
        writer.write('\n');
        IndentingWriter fieldWriter = writer;
        String fieldString = ReferenceUtil.getShortFieldDescriptor(field);
        if (!writtenFields.add(fieldString)) {
            writer.write("# duplicate field ignored\n");
            fieldWriter = new CommentingIndentingWriter(writer);
            System.err.println(String.format("Ignoring duplicate field: %s->%s", classDef.getType(), fieldString));
        } else if (staticFields.contains(fieldString)) {
            System.err.println(String.format("Duplicate static+instance field found: %s->%s", classDef.getType(), fieldString));
            System.err.println("You will need to rename one of these fields, including all references.");
            writer.write("# There is both a static and instance field with this signature.\n" + "# You will need to rename one of these fields, including all references.\n");
        }
        FieldDefinition.writeTo(options, fieldWriter, field, false);
    }
}
Also used : IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 13 with IndentingWriter

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

the class ClassDefinition method writeVirtualMethods.

private void writeVirtualMethods(IndentingWriter writer, Set<String> directMethods) throws IOException {
    boolean wroteHeader = false;
    Set<String> writtenMethods = new HashSet<String>();
    Iterable<? extends Method> virtualMethods;
    if (classDef instanceof DexBackedClassDef) {
        virtualMethods = ((DexBackedClassDef) classDef).getVirtualMethods(false);
    } else {
        virtualMethods = classDef.getVirtualMethods();
    }
    for (Method method : virtualMethods) {
        if (!wroteHeader) {
            writer.write("\n\n");
            writer.write("# virtual methods");
            wroteHeader = true;
        }
        writer.write('\n');
        // TODO: check for method validation errors
        String methodString = ReferenceUtil.getMethodDescriptor(method, true);
        IndentingWriter methodWriter = writer;
        if (!writtenMethods.add(methodString)) {
            writer.write("# duplicate method ignored\n");
            methodWriter = new CommentingIndentingWriter(writer);
        } else if (directMethods.contains(methodString)) {
            writer.write("# There is both a direct and virtual method with this signature.\n" + "# You will need to rename one of these methods, including all references.\n");
            System.err.println(String.format("Duplicate direct+virtual method found: %s->%s", classDef.getType(), methodString));
            System.err.println("You will need to rename one of these methods, including all references.");
        }
        MethodImplementation methodImpl = method.getImplementation();
        if (methodImpl == null) {
            MethodDefinition.writeEmptyMethodTo(methodWriter, method, options);
        } else {
            MethodDefinition methodDefinition = new MethodDefinition(this, method, methodImpl);
            methodDefinition.writeTo(methodWriter);
        }
    }
}
Also used : IndentingWriter(org.jf.util.IndentingWriter) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef)

Example 14 with IndentingWriter

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

the class AfBakSmali method disassembleClass.

/**
     * 生成apatch的smali文件
     * @param classDef
     * @param fileNameHandler
     * @param options
     * @param isScan
     * @param fullMethod
     * @return
     */
public static boolean disassembleClass(ClassDef classDef, ClassFileNameHandler fileNameHandler, baksmaliOptions options, boolean isScan, boolean fullMethod) {
    /**
         * 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 = TypeGenUtil.newType(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, isScan, fullMethod);
    //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 : FileOutputStream(java.io.FileOutputStream) IndentingWriter(org.jf.util.IndentingWriter) OutputStreamWriter(java.io.OutputStreamWriter) ClassDefinition(com.taobao.android.baksmali.adaptors.ClassDefinition) File(java.io.File) IndentingWriter(org.jf.util.IndentingWriter) BufferedWriter(java.io.BufferedWriter) Writer(java.io.Writer) OutputStreamWriter(java.io.OutputStreamWriter) BufferedWriter(java.io.BufferedWriter)

Example 15 with IndentingWriter

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

the class MethodDefinition method addAnalyzedInstructionMethodItems.

private void addAnalyzedInstructionMethodItems(List<MethodItem> methodItems) {
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classDef.options.classPath, method, classDef.options.inlineResolver);
    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.addCodeOffsets) {
            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 : EndPrologueMethodItem(com.taobao.android.baksmali.adaptors.Debug.EndPrologueMethodItem) DebugMethodItem(com.taobao.android.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)

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