Search in sources :

Example 1 with ClassVisitorFactory

use of com.googlecode.d2j.dex.ClassVisitorFactory in project dex2jar by pxb1988.

the class Dex2jarMultiThreadCmd method run0.

private void run0(String fileName, final ExecutorService executorService) throws IOException {
    // long baseTS = System.currentTimeMillis();
    String baseName = getBaseName(new File(fileName).toPath());
    Path currentDir = new File(".").toPath();
    Path file = currentDir.resolve(baseName + "-dex2jar.jar");
    final Path errorFile = currentDir.resolve(baseName + "-error.zip");
    System.err.println("dex2jar " + fileName + " -> " + file);
    final BaksmaliBaseDexExceptionHandler exceptionHandler = new BaksmaliBaseDexExceptionHandler();
    BaseDexFileReader reader = MultiDexFileReader.open(Files.readAllBytes(new File(fileName).toPath()));
    DexFileNode fileNode = new DexFileNode();
    try {
        reader.accept(fileNode, DexFileReader.SKIP_DEBUG | DexFileReader.IGNORE_READ_EXCEPTION);
    } catch (Exception ex) {
        exceptionHandler.handleFileException(ex);
        throw ex;
    }
    final FileSystem fs = createZip(file);
    final Path dist = fs.getPath("/");
    ClassVisitorFactory cvf = new ClassVisitorFactory() {

        @Override
        public ClassVisitor create(final String name) {
            return new ClassVisitor(Opcodes.ASM4, new ClassWriter(ClassWriter.COMPUTE_MAXS)) {

                @Override
                public void visitEnd() {
                    super.visitEnd();
                    ClassWriter cw = (ClassWriter) super.cv;
                    byte[] data;
                    try {
                        // FIXME handle 'java.lang.RuntimeException: Method code too large!'
                        data = cw.toByteArray();
                    } catch (Exception ex) {
                        System.err.println(String.format("ASM fail to generate .class file: %s", name));
                        exceptionHandler.handleFileException(ex);
                        return;
                    }
                    try {
                        Path dist1 = dist.resolve(name + ".class");
                        BaseCmd.createParentDirectories(dist1);
                        Files.write(dist1, data);
                    } catch (IOException e) {
                        exceptionHandler.handleFileException(e);
                    }
                }
            };
        }
    };
    new ExDex2Asm(exceptionHandler) {

        @Override
        public void convertDex(DexFileNode fileNode, final ClassVisitorFactory cvf) {
            if (fileNode.clzs != null) {
                final Map<String, Clz> classes = collectClzInfo(fileNode);
                final List<Future<?>> results = new ArrayList<>(fileNode.clzs.size());
                for (final DexClassNode classNode : fileNode.clzs) {
                    results.add(executorService.submit(new Runnable() {

                        @Override
                        public void run() {
                            convertClass(classNode, cvf, classes);
                        }
                    }));
                }
                executorService.submit(new Runnable() {

                    @Override
                    public void run() {
                        for (Future<?> result : results) {
                            try {
                                result.get();
                            } catch (InterruptedException | ExecutionException e) {
                                e.printStackTrace();
                            }
                        }
                        BaksmaliBaseDexExceptionHandler exceptionHandler1 = (BaksmaliBaseDexExceptionHandler) exceptionHandler;
                        if (exceptionHandler1.hasException()) {
                            exceptionHandler1.dump(errorFile, new String[0]);
                        }
                        try {
                            fs.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
        }
    }.convertDex(fileNode, cvf);
}
Also used : Path(java.nio.file.Path) ClassVisitor(org.objectweb.asm.ClassVisitor) IOException(java.io.IOException) IOException(java.io.IOException) ClassWriter(org.objectweb.asm.ClassWriter) DexClassNode(com.googlecode.d2j.node.DexClassNode) FileSystem(java.nio.file.FileSystem) DexFileNode(com.googlecode.d2j.node.DexFileNode) ClassVisitorFactory(com.googlecode.d2j.dex.ClassVisitorFactory) BaseDexFileReader(com.googlecode.d2j.reader.BaseDexFileReader) File(java.io.File) ExDex2Asm(com.googlecode.d2j.dex.ExDex2Asm)

Example 2 with ClassVisitorFactory

use of com.googlecode.d2j.dex.ClassVisitorFactory in project dex2jar by pxb1988.

the class TestUtils method translateAndCheck.

public static byte[] translateAndCheck(DexFileNode fileNode, DexClassNode clzNode) throws AnalyzerException, IllegalAccessException {
    // 1. convert to .class
    Dex2Asm dex2Asm = new Dex2Asm() {

        @Override
        public void convertCode(DexMethodNode methodNode, MethodVisitor mv) {
            try {
                super.convertCode(methodNode, mv);
            } catch (Exception ex) {
                BaksmaliDumper d = new BaksmaliDumper();
                try {
                    BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.err, "UTF-8"));
                    d.baksmaliMethod(methodNode, out);
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                throw new DexException(ex, "fail convert code %s", methodNode.method);
            }
        }
    };
    final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    ClassVisitorFactory cvf = new ClassVisitorFactory() {

        @Override
        public ClassVisitor create(String classInternalName) {
            return cw;
        }
    };
    if (fileNode != null) {
        dex2Asm.convertClass(clzNode, cvf, fileNode);
    } else {
        dex2Asm.convertClass(clzNode, cvf);
    }
    byte[] data = cw.toByteArray();
    // 2. verify .class
    ClassReader cr = new ClassReader(data);
    TestUtils.verify(cr);
    // 3. convert back to dex
    CfOptions cfOptions = new CfOptions();
    cfOptions.strictNameCheck = false;
    DexOptions dexOptions = new DexOptions();
    DirectClassFile dcf = new DirectClassFile(data, clzNode.className.substring(1, clzNode.className.length() - 1) + ".class", true);
    dcf.setAttributeFactory(new StdAttributeFactory());
    com.android.dx.dex.file.DexFile dxFile = new com.android.dx.dex.file.DexFile(dexOptions);
    CfTranslator.translate(dcf, data, cfOptions, dexOptions, dxFile);
    return data;
}
Also used : DexException(com.googlecode.d2j.DexException) BaksmaliDumper(com.googlecode.d2j.smali.BaksmaliDumper) StdAttributeFactory(com.android.dx.cf.direct.StdAttributeFactory) MethodVisitor(org.objectweb.asm.MethodVisitor) TraceMethodVisitor(org.objectweb.asm.util.TraceMethodVisitor) Dex2Asm(com.googlecode.d2j.dex.Dex2Asm) DexMethodNode(com.googlecode.d2j.node.DexMethodNode) DexOptions(com.android.dx.dex.DexOptions) AnalyzerException(org.objectweb.asm.tree.analysis.AnalyzerException) DexException(com.googlecode.d2j.DexException) ZipException(java.util.zip.ZipException) ClassWriter(org.objectweb.asm.ClassWriter) DirectClassFile(com.android.dx.cf.direct.DirectClassFile) ClassReader(org.objectweb.asm.ClassReader) ClassVisitorFactory(com.googlecode.d2j.dex.ClassVisitorFactory) CfOptions(com.android.dx.dex.cf.CfOptions)

Example 3 with ClassVisitorFactory

use of com.googlecode.d2j.dex.ClassVisitorFactory in project dex2jar by pxb1988.

the class GenerateCompileStubFromOdex method doDex.

private void doDex(ByteBuffer bs, final Path out) {
    DexFileReader reader = new DexFileReader(bs);
    DexFileNode fileNode = new DexFileNode();
    reader.accept(fileNode, DexFileReader.SKIP_CODE);
    Dex2Asm dex2Asm = new Dex2Asm();
    dex2Asm.convertDex(fileNode, new ClassVisitorFactory() {

        @Override
        public ClassVisitor create(final String classInternalName) {
            final Path target = out.resolve(classInternalName + ".class");
            if (Files.exists(target)) {
                System.err.println("class " + classInternalName + " is already exists, skipping.");
                return null;
            }
            return new ClassVisitor(Opcodes.ASM4, new ClassWriter(ClassWriter.COMPUTE_MAXS)) {

                @Override
                public void visitEnd() {
                    super.visitEnd();
                    ClassWriter cw = (ClassWriter) cv;
                    byte[] data = cw.toByteArray();
                    try {
                        BaseCmd.createParentDirectories(target);
                        Files.write(target, data);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
                    if (noPrivate && 0 != (access & Opcodes.ACC_PRIVATE)) {
                        return null;
                    }
                    return super.visitField(access, name, desc, signature, value);
                }

                @Override
                public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
                    if (noPrivate && 0 != (access & Opcodes.ACC_PRIVATE)) {
                        return null;
                    }
                    MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
                    if (0 != ((Opcodes.ACC_NATIVE | Opcodes.ACC_ABSTRACT) & access)) {
                        return mv;
                    }
                    mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
                    mv.visitInsn(Opcodes.DUP);
                    mv.visitLdcInsn("stub");
                    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
                    mv.visitInsn(Opcodes.ATHROW);
                    return mv;
                }
            };
        }
    });
}
Also used : Path(java.nio.file.Path) DexFileReader(com.googlecode.d2j.reader.DexFileReader) IOException(java.io.IOException) Dex2Asm(com.googlecode.d2j.dex.Dex2Asm) DexFileNode(com.googlecode.d2j.node.DexFileNode) ClassVisitorFactory(com.googlecode.d2j.dex.ClassVisitorFactory)

Aggregations

ClassVisitorFactory (com.googlecode.d2j.dex.ClassVisitorFactory)3 Dex2Asm (com.googlecode.d2j.dex.Dex2Asm)2 DexFileNode (com.googlecode.d2j.node.DexFileNode)2 IOException (java.io.IOException)2 Path (java.nio.file.Path)2 ClassWriter (org.objectweb.asm.ClassWriter)2 DirectClassFile (com.android.dx.cf.direct.DirectClassFile)1 StdAttributeFactory (com.android.dx.cf.direct.StdAttributeFactory)1 DexOptions (com.android.dx.dex.DexOptions)1 CfOptions (com.android.dx.dex.cf.CfOptions)1 DexException (com.googlecode.d2j.DexException)1 ExDex2Asm (com.googlecode.d2j.dex.ExDex2Asm)1 DexClassNode (com.googlecode.d2j.node.DexClassNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 BaseDexFileReader (com.googlecode.d2j.reader.BaseDexFileReader)1 DexFileReader (com.googlecode.d2j.reader.DexFileReader)1 BaksmaliDumper (com.googlecode.d2j.smali.BaksmaliDumper)1 File (java.io.File)1 FileSystem (java.nio.file.FileSystem)1 ZipException (java.util.zip.ZipException)1