Search in sources :

Example 1 with LambadaNameSafeClassAdapter

use of com.googlecode.d2j.dex.LambadaNameSafeClassAdapter 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) {
            final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            final LambadaNameSafeClassAdapter rca = new LambadaNameSafeClassAdapter(cw);
            return new ClassVisitor(Opcodes.ASM4, rca) {

                @Override
                public void visitEnd() {
                    super.visitEnd();
                    String className = rca.getClassName();
                    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", className));
                        exceptionHandler.handleFileException(ex);
                        return;
                    }
                    try {
                        Path dist1 = dist.resolve(className + ".class");
                        BaseCmd.createParentDirectories(dist1);
                        Files.write(dist1, data);
                    } catch (IOException e) {
                        exceptionHandler.handleFileException(e);
                    }
                }
            };
        }
    };
    new ExDex2Asm(exceptionHandler) {

        @Override
        public void convertDex(final 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(fileNode, 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 : LambadaNameSafeClassAdapter(com.googlecode.d2j.dex.LambadaNameSafeClassAdapter) ClassVisitor(org.objectweb.asm.ClassVisitor) DexClassNode(com.googlecode.d2j.node.DexClassNode) FileSystem(java.nio.file.FileSystem) ExDex2Asm(com.googlecode.d2j.dex.ExDex2Asm) Path(java.nio.file.Path) IOException(java.io.IOException) IOException(java.io.IOException) ClassWriter(org.objectweb.asm.ClassWriter) DexFileNode(com.googlecode.d2j.node.DexFileNode) ClassVisitorFactory(com.googlecode.d2j.dex.ClassVisitorFactory) BaseDexFileReader(com.googlecode.d2j.reader.BaseDexFileReader) File(java.io.File)

Example 2 with LambadaNameSafeClassAdapter

use of com.googlecode.d2j.dex.LambadaNameSafeClassAdapter 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, ClzCtx clzCtx) {
            try {
                super.convertCode(methodNode, mv, clzCtx);
            } 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, "Failed to convert code for %s", methodNode.method);
            }
        }
    };
    final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    final LambadaNameSafeClassAdapter rca = new LambadaNameSafeClassAdapter(cw);
    ClassVisitorFactory cvf = new ClassVisitorFactory() {

        @Override
        public ClassVisitor create(String classInternalName) {
            return rca;
        }
    };
    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();
    if (fileNode != null && fileNode.dexVersion >= DexConstants.DEX_037) {
        dexOptions.minSdkVersion = 26;
    }
    DirectClassFile dcf = new DirectClassFile(data, rca.getClassName() + ".class", true);
    dcf.setAttributeFactory(new StdAttributeFactory());
    com.android.dx.dex.file.DexFile dxFile = new com.android.dx.dex.file.DexFile(dexOptions);
    try {
        CfTranslator.translate(new DxContext(), dcf, data, cfOptions, dexOptions, dxFile);
    } catch (ParseException e) {
        if ("MethodHandle not supported".equals(e.getMessage())) {
            e.printStackTrace();
        } else {
            throw e;
        }
    }
    return data;
}
Also used : DexException(com.googlecode.d2j.DexException) BaksmaliDumper(com.googlecode.d2j.smali.BaksmaliDumper) LambadaNameSafeClassAdapter(com.googlecode.d2j.dex.LambadaNameSafeClassAdapter) 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) ParseException(com.android.dx.cf.iface.ParseException) ClassWriter(org.objectweb.asm.ClassWriter) DxContext(com.android.dx.command.dexer.DxContext) 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) ParseException(com.android.dx.cf.iface.ParseException)

Aggregations

ClassVisitorFactory (com.googlecode.d2j.dex.ClassVisitorFactory)2 LambadaNameSafeClassAdapter (com.googlecode.d2j.dex.LambadaNameSafeClassAdapter)2 ClassWriter (org.objectweb.asm.ClassWriter)2 DirectClassFile (com.android.dx.cf.direct.DirectClassFile)1 StdAttributeFactory (com.android.dx.cf.direct.StdAttributeFactory)1 ParseException (com.android.dx.cf.iface.ParseException)1 DxContext (com.android.dx.command.dexer.DxContext)1 DexOptions (com.android.dx.dex.DexOptions)1 CfOptions (com.android.dx.dex.cf.CfOptions)1 DexException (com.googlecode.d2j.DexException)1 Dex2Asm (com.googlecode.d2j.dex.Dex2Asm)1 ExDex2Asm (com.googlecode.d2j.dex.ExDex2Asm)1 DexClassNode (com.googlecode.d2j.node.DexClassNode)1 DexFileNode (com.googlecode.d2j.node.DexFileNode)1 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)1 BaseDexFileReader (com.googlecode.d2j.reader.BaseDexFileReader)1 BaksmaliDumper (com.googlecode.d2j.smali.BaksmaliDumper)1 File (java.io.File)1 IOException (java.io.IOException)1 FileSystem (java.nio.file.FileSystem)1