Search in sources :

Example 1 with ClassFileNameHandler

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

the class ApkPatch method buildPrepareClass.

private static Set<String> buildPrepareClass(File smaliDir, List<File> newFiles, DexDiffInfo info) throws PatchException {
    Set<DexBackedClassDef> classes = Sets.newHashSet();
    classes = SmaliDiffUtils.scanClasses(smaliDir, newFiles);
    ArrayList<String> methods = new ArrayList<String>();
    {
        Set<DexBackedMethod> tempSet = info.getModifiedMethods();
        for (DexBackedMethod methodRef : tempSet) {
            String template = methodRef.getDefiningClass() + "->" + methodRef.getName();
            methods.add(template);
            System.out.println("template: " + template);
            if (superClasses.containsKey(methodRef.getDefiningClass())) {
                ArrayList<String> derivedClasses = superClasses.get(methodRef.getDefiningClass());
                for (int i = 0; i < derivedClasses.size(); i++) {
                    template = derivedClasses.get(i) + "->" + methodRef.getName();
                    System.out.println("template: " + template);
                    methods.add(template);
                }
            }
        }
    }
    Set<String> prepareClasses = new HashSet<String>();
    try {
        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        for (DexBackedClassDef classDef : classes) {
            currentClassType = null;
            String className = TypeGenUtil.newType(classDef.getType());
            // baksmali.disassembleClass(classDef, outFileNameHandler, options);
            File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
            if (!smaliFile.exists()) {
                continue;
            }
            //增加class注解到prepare
            getClassAnnotaionPrepareClasses(classDef, prepareClasses, info);
            BufferedReader br = new BufferedReader(new FileReader(smaliFile));
            // 一次读入一行,直到读入null为文件结束
            String data = br.readLine();
            while (data != null) {
                boolean find = false;
                for (String m : methods) {
                    if (data.contains(m)) {
                        find = true;
                        break;
                    }
                }
                if (find) {
                    prepareClasses.add(className.substring(1, className.length() - 1).replace('/', '.'));
                    System.out.println("prepare class: " + className);
                    break;
                }
                // 接着读下一行
                data = br.readLine();
            }
            br.close();
        }
    } catch (Exception e) {
        throw new PatchException(e);
    }
    for (DexBackedMethod method : info.getModifiedMethods()) {
        prepareClasses.add(method.getDefiningClass().substring(1, method.getDefiningClass().length() - 1).replace("/", "."));
    }
    //        getMethodAnnotaionPrepareClasses(info,prepareClasses);
    return prepareClasses;
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) DexBackedMethod(org.jf.dexlib2.dexbacked.DexBackedMethod) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) ArrayList(java.util.ArrayList) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException) BufferedReader(java.io.BufferedReader) FileReader(java.io.FileReader) PatchException(com.taobao.android.differ.dex.PatchException) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) File(java.io.File) HashSet(java.util.HashSet)

Example 2 with ClassFileNameHandler

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

the class SmaliDiffUtils method disassemble.

public static File disassemble(File smaliDir, DexBackedClassDef dexBackedClassDef) throws PatchException {
    Set<DexBackedClassDef> classes = Sets.newHashSet();
    classes.add(dexBackedClassDef);
    final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
    final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
    String className = dexBackedClassDef.getType();
    AfBakSmali.disassembleClass(dexBackedClassDef, outFileNameHandler, getBuildOption(classes, 19), true, false);
    File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
    return smaliFile;
}
Also used : ClassFileNameHandler(org.jf.util.ClassFileNameHandler) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File)

Example 3 with ClassFileNameHandler

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

the class SmaliDiffUtils method scanClasses.

public static Set<DexBackedClassDef> scanClasses(File smaliDir, List<File> newFiles) throws PatchException {
    Set<DexBackedClassDef> classes = Sets.newHashSet();
    try {
        for (File newFile : newFiles) {
            DexBackedDexFile newDexFile = DexFileFactory.loadDexFile(newFile, 19, true);
            Set<? extends DexBackedClassDef> dexClasses = newDexFile.getClasses();
            classes.addAll(dexClasses);
        }
        final ClassFileNameHandler outFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        final ClassFileNameHandler inFileNameHandler = new ClassFileNameHandler(smaliDir, ".smali");
        for (DexBackedClassDef classDef : classes) {
            String className = classDef.getType();
            ApkPatch.currentClassType = null;
            AfBakSmali.disassembleClass(classDef, outFileNameHandler, getBuildOption(classes, 19), true, true);
            File smaliFile = inFileNameHandler.getUniqueFilenameForClass(className);
        }
    } catch (Exception e) {
        throw new PatchException(e);
    }
    return classes;
}
Also used : DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) PatchException(com.taobao.android.differ.dex.PatchException) DexBackedClassDef(org.jf.dexlib2.dexbacked.DexBackedClassDef) DexBackedDexFile(org.jf.dexlib2.dexbacked.DexBackedDexFile) File(java.io.File) RecognitionException(org.antlr.runtime.RecognitionException) PatchException(com.taobao.android.differ.dex.PatchException) IOException(java.io.IOException)

Example 4 with ClassFileNameHandler

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

the class BakSmali method disassembleDexFile.

public static boolean disassembleDexFile(DexFile dexFile, final baksmaliOptions options) {
    if (options.registerInfo != 0 || options.deodex) {
        try {
            Iterable<String> extraClassPathEntries;
            if (options.extraClassPathEntries != null) {
                extraClassPathEntries = options.extraClassPathEntries;
            } else {
                extraClassPathEntries = ImmutableList.of();
            }
            options.classPath = ClassPath.fromClassPath(options.bootClassPathDirs, Iterables.concat(options.bootClassPathEntries, extraClassPathEntries), dexFile, options.apiLevel, options.checkPackagePrivateAccess, options.experimental);
            if (options.customInlineDefinitions != null) {
                options.inlineResolver = new CustomInlineMethodResolver(options.classPath, options.customInlineDefinitions);
            }
        } catch (Exception ex) {
            System.err.println("\n\nError occurred while loading boot class path files. Aborting.");
            ex.printStackTrace(System.err);
            return false;
        }
    }
    if (options.resourceIdFileEntries != null) {
        class PublicHandler extends DefaultHandler {

            String prefix = null;

            public PublicHandler(String prefix) {
                super();
                this.prefix = prefix;
            }

            public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
                if (qName.equals("public")) {
                    String type = attr.getValue("type");
                    String name = attr.getValue("name").replace('.', '_');
                    Integer public_key = Integer.decode(attr.getValue("id"));
                    String public_val = new StringBuffer().append(prefix).append(".").append(type).append(".").append(name).toString();
                    options.resourceIds.put(public_key, public_val);
                }
            }
        }
        ;
        for (Map.Entry<String, String> entry : options.resourceIdFileEntries.entrySet()) {
            try {
                SAXParser saxp = SAXParserFactory.newInstance().newSAXParser();
                String prefix = entry.getValue();
                saxp.parse(entry.getKey(), new PublicHandler(prefix));
            } catch (ParserConfigurationException e) {
                continue;
            } catch (SAXException e) {
                continue;
            } catch (IOException e) {
                continue;
            }
        }
    }
    File outputDirectoryFile = new File(options.outputDirectory);
    if (!outputDirectoryFile.exists()) {
        if (!outputDirectoryFile.mkdirs()) {
            System.err.println("Can't create the output directory " + options.outputDirectory);
            return false;
        }
    }
    //sort the classes, so that if we're on a case-insensitive file system and need to handle classes with file
    //name collisions, then we'll use the same name for each class, if the dex file goes through multiple
    //baksmali/smali cycles for some reason. If a class with a colliding name is added or removed, the filenames
    //may still change of course
    List<? extends ClassDef> classDefs = Ordering.natural().sortedCopy(dexFile.getClasses());
    if (!options.noAccessorComments) {
        options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
    }
    final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
    ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
    List<Future<Boolean>> tasks = Lists.newArrayList();
    for (final ClassDef classDef : classDefs) {
        tasks.add(executor.submit(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                return disassembleClass(classDef, fileNameHandler, options);
            }
        }));
    }
    boolean errorOccurred = false;
    try {
        for (Future<Boolean> task : tasks) {
            while (true) {
                try {
                    if (!task.get()) {
                        errorOccurred = true;
                    }
                } catch (InterruptedException ex) {
                    continue;
                } catch (ExecutionException ex) {
                    throw new RuntimeException(ex);
                }
                break;
            }
        }
    } finally {
        executor.shutdown();
    }
    return !errorOccurred;
}
Also used : CustomInlineMethodResolver(org.jf.dexlib2.analysis.CustomInlineMethodResolver) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) Attributes(org.xml.sax.Attributes) SAXException(org.xml.sax.SAXException) SyntheticAccessorResolver(org.jf.dexlib2.util.SyntheticAccessorResolver) ClassDef(org.jf.dexlib2.iface.ClassDef) SAXParser(javax.xml.parsers.SAXParser) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SAXException(org.xml.sax.SAXException) DefaultHandler(org.xml.sax.helpers.DefaultHandler) Map(java.util.Map) DexFile(org.jf.dexlib2.iface.DexFile)

Example 5 with ClassFileNameHandler

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

the class SmaliUtils method disassembleDexFile.

/**
     * 将dex文件转换为smali文件
     * @param dex
     * @param outputDir
     * @param includeClasses 需要做过滤的文件
     */
public static boolean disassembleDexFile(File dex, File outputDir, final Set<String> includeClasses) throws IOException {
    final baksmaliOptions options = createBaksmaliOptions();
    if (!outputDir.exists()) {
        outputDir.mkdirs();
    }
    DexFile dexFile = DexFileFactory.loadDexFile(dex, DEFAULT_API_LEVEL, true);
    options.outputDirectory = outputDir.getAbsolutePath();
    //1. 设置线程数
    options.jobs = 3;
    if (options.registerInfo != 0 || options.deodex) {
        try {
            Iterable<String> extraClassPathEntries;
            if (options.extraClassPathEntries != null) {
                extraClassPathEntries = options.extraClassPathEntries;
            } else {
                extraClassPathEntries = ImmutableList.of();
            }
            options.classPath = ClassPath.fromClassPath(options.bootClassPathDirs, Iterables.concat(options.bootClassPathEntries, extraClassPathEntries), dexFile, options.apiLevel, options.checkPackagePrivateAccess, options.experimental);
            if (options.customInlineDefinitions != null) {
                options.inlineResolver = new CustomInlineMethodResolver(options.classPath, options.customInlineDefinitions);
            }
        } catch (Exception ex) {
            System.err.println("\n\nError occurred while loading boot class path files. Aborting.");
            ex.printStackTrace(System.err);
            return false;
        }
    }
    if (options.resourceIdFileEntries != null) {
        class PublicHandler extends DefaultHandler {

            String prefix = null;

            public PublicHandler(String prefix) {
                super();
                this.prefix = prefix;
            }

            public void startElement(String uri, String localName, String qName, Attributes attr) throws SAXException {
                if (qName.equals("public")) {
                    String type = attr.getValue("type");
                    String name = attr.getValue("name").replace('.', '_');
                    Integer public_key = Integer.decode(attr.getValue("id"));
                    String public_val = new StringBuffer().append(prefix).append(".").append(type).append(".").append(name).toString();
                    options.resourceIds.put(public_key, public_val);
                }
            }
        }
        ;
        for (Map.Entry<String, String> entry : options.resourceIdFileEntries.entrySet()) {
            try {
                SAXParser saxp = SAXParserFactory.newInstance().newSAXParser();
                String prefix = entry.getValue();
                saxp.parse(entry.getKey(), new PublicHandler(prefix));
            } catch (ParserConfigurationException e) {
                continue;
            } catch (SAXException e) {
                continue;
            } catch (IOException e) {
                continue;
            }
        }
    }
    File outputDirectoryFile = new File(options.outputDirectory);
    if (!outputDirectoryFile.exists()) {
        if (!outputDirectoryFile.mkdirs()) {
            System.err.println("Can't create the output directory " + options.outputDirectory);
            return false;
        }
    }
    // sort the classes, so that if we're on a case-insensitive file system and need to handle classes with file
    // name collisions, then we'll use the same name for each class, if the dex file goes through multiple
    // baksmali/smali cycles for some reason. If a class with a colliding name is added or removed, the filenames
    // may still change of course
    List<? extends ClassDef> classDefs = Ordering.natural().sortedCopy(dexFile.getClasses());
    if (!options.noAccessorComments) {
        options.syntheticAccessorResolver = new SyntheticAccessorResolver(classDefs);
    }
    final ClassFileNameHandler fileNameHandler = new ClassFileNameHandler(outputDirectoryFile, ".smali");
    ExecutorService executor = Executors.newFixedThreadPool(options.jobs);
    List<Future<Boolean>> tasks = Lists.newArrayList();
    for (final ClassDef classDef : classDefs) {
        tasks.add(executor.submit(new Callable<Boolean>() {

            @Override
            public Boolean call() throws Exception {
                String className = getDalvikClassName(classDef.getType());
                if (null != includeClasses) {
                    if (includeClasses.contains(className)) {
                        BakSmali.disassembleClass(classDef, fileNameHandler, options);
                    }
                    return true;
                } else {
                    return BakSmali.disassembleClass(classDef, fileNameHandler, options);
                }
            }
        }));
    }
    boolean errorOccurred = false;
    try {
        for (Future<Boolean> task : tasks) {
            while (true) {
                try {
                    if (!task.get()) {
                        errorOccurred = true;
                    }
                } catch (InterruptedException ex) {
                    continue;
                } catch (ExecutionException ex) {
                    throw new RuntimeException(ex);
                }
                break;
            }
        }
    } finally {
        executor.shutdown();
    }
    return !errorOccurred;
}
Also used : org.jf.baksmali.baksmaliOptions(org.jf.baksmali.baksmaliOptions) CustomInlineMethodResolver(org.jf.dexlib2.analysis.CustomInlineMethodResolver) ClassFileNameHandler(org.jf.util.ClassFileNameHandler) Attributes(org.xml.sax.Attributes) SAXException(org.xml.sax.SAXException) SyntheticAccessorResolver(org.jf.dexlib2.util.SyntheticAccessorResolver) ClassDef(org.jf.dexlib2.iface.ClassDef) SAXParser(javax.xml.parsers.SAXParser) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) IOException(java.io.IOException) DexFile(org.jf.dexlib2.iface.DexFile) RecognitionException(org.antlr.runtime.RecognitionException) IOException(java.io.IOException) ParserConfigurationException(javax.xml.parsers.ParserConfigurationException) SAXException(org.xml.sax.SAXException) DefaultHandler(org.xml.sax.helpers.DefaultHandler) Map(java.util.Map) File(java.io.File) DexFile(org.jf.dexlib2.iface.DexFile)

Aggregations

ClassFileNameHandler (org.jf.util.ClassFileNameHandler)7 File (java.io.File)5 DexBackedClassDef (org.jf.dexlib2.dexbacked.DexBackedClassDef)4 IOException (java.io.IOException)3 DexBackedDexFile (org.jf.dexlib2.dexbacked.DexBackedDexFile)3 ClassDef (org.jf.dexlib2.iface.ClassDef)3 PatchException (com.taobao.android.differ.dex.PatchException)2 HashSet (java.util.HashSet)2 Map (java.util.Map)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 SAXParser (javax.xml.parsers.SAXParser)2 RecognitionException (org.antlr.runtime.RecognitionException)2 CustomInlineMethodResolver (org.jf.dexlib2.analysis.CustomInlineMethodResolver)2 DexFile (org.jf.dexlib2.iface.DexFile)2 SyntheticAccessorResolver (org.jf.dexlib2.util.SyntheticAccessorResolver)2 Attributes (org.xml.sax.Attributes)2 SAXException (org.xml.sax.SAXException)2 DefaultHandler (org.xml.sax.helpers.DefaultHandler)2 BufferedReader (java.io.BufferedReader)1 FileReader (java.io.FileReader)1