Search in sources :

Example 1 with CustomInlineMethodResolver

use of org.jf.dexlib2.analysis.CustomInlineMethodResolver in project smali by JesusFreke.

the class CustomMethodInlineTableTest method testCustomMethodInlineTable_Static.

@Test
public void testCustomMethodInlineTable_Static() throws IOException {
    List<ImmutableInstruction> instructions = Lists.newArrayList(new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID));
    ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null);
    ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.STATIC.getValue(), null, methodImpl);
    ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null);
    DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef));
    ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile);
    ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART);
    InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
    Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0);
    Assert.assertEquals(Opcode.INVOKE_STATIC, deodexedInstruction.getOpcode());
    MethodReference methodReference = (MethodReference) ((Instruction35c) deodexedInstruction).getReference();
    Assert.assertEquals(method, methodReference);
}
Also used : ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ImmutableInstruction(org.jf.dexlib2.immutable.instruction.ImmutableInstruction) ImmutableInstruction10x(org.jf.dexlib2.immutable.instruction.ImmutableInstruction10x) DexFile(org.jf.dexlib2.iface.DexFile) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) ImmutableInstruction35mi(org.jf.dexlib2.immutable.instruction.ImmutableInstruction35mi) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) ImmutableInstruction(org.jf.dexlib2.immutable.instruction.ImmutableInstruction) ImmutableMethodImplementation(org.jf.dexlib2.immutable.ImmutableMethodImplementation) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) Test(org.junit.Test)

Example 2 with CustomInlineMethodResolver

use of org.jf.dexlib2.analysis.CustomInlineMethodResolver in project smali by JesusFreke.

the class CustomMethodInlineTableTest method testCustomMethodInlineTable_Direct.

@Test
public void testCustomMethodInlineTable_Direct() throws IOException {
    List<ImmutableInstruction> instructions = Lists.newArrayList(new ImmutableInstruction35mi(Opcode.EXECUTE_INLINE, 1, 0, 0, 0, 0, 0, 0), new ImmutableInstruction10x(Opcode.RETURN_VOID));
    ImmutableMethodImplementation methodImpl = new ImmutableMethodImplementation(1, instructions, null, null);
    ImmutableMethod method = new ImmutableMethod("Lblah;", "blah", null, "V", AccessFlags.PRIVATE.getValue(), null, methodImpl);
    ClassDef classDef = new ImmutableClassDef("Lblah;", AccessFlags.PUBLIC.getValue(), "Ljava/lang/Object;", null, null, null, null, null, ImmutableList.of(method), null);
    DexFile dexFile = new ImmutableDexFile(Opcodes.getDefault(), ImmutableList.of(classDef));
    ClassPathResolver resolver = new ClassPathResolver(ImmutableList.<String>of(), ImmutableList.<String>of(), ImmutableList.<String>of(), dexFile);
    ClassPath classPath = new ClassPath(resolver.getResolvedClassProviders(), false, ClassPath.NOT_ART);
    InlineMethodResolver inlineMethodResolver = new CustomInlineMethodResolver(classPath, "Lblah;->blah()V");
    MethodAnalyzer methodAnalyzer = new MethodAnalyzer(classPath, method, inlineMethodResolver, false);
    Instruction deodexedInstruction = methodAnalyzer.getInstructions().get(0);
    Assert.assertEquals(Opcode.INVOKE_DIRECT, deodexedInstruction.getOpcode());
    MethodReference methodReference = (MethodReference) ((Instruction35c) deodexedInstruction).getReference();
    Assert.assertEquals(method, methodReference);
}
Also used : ImmutableMethod(org.jf.dexlib2.immutable.ImmutableMethod) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) Instruction(org.jf.dexlib2.iface.instruction.Instruction) ImmutableInstruction(org.jf.dexlib2.immutable.instruction.ImmutableInstruction) ImmutableInstruction10x(org.jf.dexlib2.immutable.instruction.ImmutableInstruction10x) DexFile(org.jf.dexlib2.iface.DexFile) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) ImmutableInstruction35mi(org.jf.dexlib2.immutable.instruction.ImmutableInstruction35mi) ImmutableClassDef(org.jf.dexlib2.immutable.ImmutableClassDef) ClassDef(org.jf.dexlib2.iface.ClassDef) ImmutableInstruction(org.jf.dexlib2.immutable.instruction.ImmutableInstruction) ImmutableMethodImplementation(org.jf.dexlib2.immutable.ImmutableMethodImplementation) MethodReference(org.jf.dexlib2.iface.reference.MethodReference) ImmutableDexFile(org.jf.dexlib2.immutable.ImmutableDexFile) Test(org.junit.Test)

Example 3 with CustomInlineMethodResolver

use of org.jf.dexlib2.analysis.CustomInlineMethodResolver 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 4 with CustomInlineMethodResolver

use of org.jf.dexlib2.analysis.CustomInlineMethodResolver 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)

Example 5 with CustomInlineMethodResolver

use of org.jf.dexlib2.analysis.CustomInlineMethodResolver in project smali by JesusFreke.

the class DeodexCommand method getOptions.

@Override
protected BaksmaliOptions getOptions() {
    BaksmaliOptions options = super.getOptions();
    options.deodex = true;
    if (dexFile instanceof DexBackedOdexFile) {
        if (inlineTable == null) {
            options.inlineResolver = InlineMethodResolver.createInlineMethodResolver(((DexBackedOdexFile) dexFile).getOdexVersion());
        } else {
            File inlineTableFile = new File(inlineTable);
            if (!inlineTableFile.exists()) {
                System.err.println(String.format("Could not find file: %s", inlineTable));
                System.exit(-1);
            }
            try {
                options.inlineResolver = new CustomInlineMethodResolver(options.classPath, inlineTableFile);
            } catch (IOException ex) {
                System.err.println(String.format("Error while reading file: %s", inlineTableFile));
                ex.printStackTrace(System.err);
                System.exit(-1);
            }
        }
    }
    return options;
}
Also used : CustomInlineMethodResolver(org.jf.dexlib2.analysis.CustomInlineMethodResolver) DexBackedOdexFile(org.jf.dexlib2.dexbacked.DexBackedOdexFile) IOException(java.io.IOException) DexBackedOdexFile(org.jf.dexlib2.dexbacked.DexBackedOdexFile) File(java.io.File)

Aggregations

ClassDef (org.jf.dexlib2.iface.ClassDef)5 DexFile (org.jf.dexlib2.iface.DexFile)5 CustomInlineMethodResolver (org.jf.dexlib2.analysis.CustomInlineMethodResolver)3 Instruction (org.jf.dexlib2.iface.instruction.Instruction)3 MethodReference (org.jf.dexlib2.iface.reference.MethodReference)3 ImmutableClassDef (org.jf.dexlib2.immutable.ImmutableClassDef)3 ImmutableDexFile (org.jf.dexlib2.immutable.ImmutableDexFile)3 ImmutableMethod (org.jf.dexlib2.immutable.ImmutableMethod)3 ImmutableMethodImplementation (org.jf.dexlib2.immutable.ImmutableMethodImplementation)3 ImmutableInstruction (org.jf.dexlib2.immutable.instruction.ImmutableInstruction)3 ImmutableInstruction10x (org.jf.dexlib2.immutable.instruction.ImmutableInstruction10x)3 ImmutableInstruction35mi (org.jf.dexlib2.immutable.instruction.ImmutableInstruction35mi)3 Test (org.junit.Test)3 File (java.io.File)2 IOException (java.io.IOException)2 Map (java.util.Map)2 ParserConfigurationException (javax.xml.parsers.ParserConfigurationException)2 SAXParser (javax.xml.parsers.SAXParser)2 SyntheticAccessorResolver (org.jf.dexlib2.util.SyntheticAccessorResolver)2 ClassFileNameHandler (org.jf.util.ClassFileNameHandler)2