Search in sources :

Example 1 with IndentingWriter

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

the class BakSmali method disassembleClass.

public 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(com.taobao.android.baksmali.adaptors.ClassDefinition) DexFile(org.jf.dexlib2.iface.DexFile) IndentingWriter(org.jf.util.IndentingWriter) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SAXException(org.xml.sax.SAXException)

Example 2 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 3 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 4 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 5 with IndentingWriter

use of org.jf.util.IndentingWriter in project dex2jar by pxb1988.

the class SmaliTest method baksmali.

private static String baksmali(DexBackedClassDef def) throws IOException {
    baksmaliOptions opts = new baksmaliOptions();
    opts.outputDebugInfo = false;
    opts.syntheticAccessorResolver = new SyntheticAccessorResolver(Collections.EMPTY_LIST);
    ClassDefinition classDefinition = new ClassDefinition(opts, def);
    StringWriter bufWriter = new StringWriter();
    IndentingWriter writer = new IndentingWriter(bufWriter);
    classDefinition.writeTo((IndentingWriter) writer);
    writer.flush();
    return bufWriter.toString();
}
Also used : org.jf.baksmali.baksmaliOptions(org.jf.baksmali.baksmaliOptions) IndentingWriter(org.jf.util.IndentingWriter) ClassDefinition(org.jf.baksmali.Adaptors.ClassDefinition) SyntheticAccessorResolver(org.jf.dexlib2.util.SyntheticAccessorResolver)

Aggregations

IndentingWriter (org.jf.util.IndentingWriter)18 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)8 ClassDefinition (com.taobao.android.baksmali.adaptors.ClassDefinition)4 HashSet (java.util.HashSet)4 BufferedWriter (java.io.BufferedWriter)3 File (java.io.File)3 FileOutputStream (java.io.FileOutputStream)3 IOException (java.io.IOException)3 OutputStreamWriter (java.io.OutputStreamWriter)3 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)3 ClassDefinition (org.jf.baksmali.Adaptors.ClassDefinition)3 DexFile (org.jf.dexlib2.iface.DexFile)3 SAXException (org.xml.sax.SAXException)3 MethodReplaceAnnotation (com.taobao.android.apatch.annotation.MethodReplaceAnnotation)2 DebugMethodItem (com.taobao.android.baksmali.adaptors.Debug.DebugMethodItem)2 EndPrologueMethodItem (com.taobao.android.baksmali.adaptors.Debug.EndPrologueMethodItem)2 Writer (java.io.Writer)2 AnalyzedInstruction (org.jf.dexlib2.analysis.AnalyzedInstruction)2 Field (org.jf.dexlib2.iface.Field)2 Method (org.jf.dexlib2.iface.Method)2