android反编译工具整合

   公司手机团队,用ANDROID开发,为了借鉴学习别人源码,于是找来网上APK反编译的方法。

  用的主流的方法,apktools 取资源, 下载地址http://code.google.com/p/android-apktool/downloads/list

 用的 dex2jar 把dex 转成 jar

要记命令不说,烦得要命,每次都要先转资源,再用rar 取出classes.dex 然后再把这个文件 用dex2jar 转成 jar文件

 然后是用jd-gui 查看。


 仔细看了一下 apktools 和dex2jar 发现都是java写的,为什么整合一下呢? why not ?

  于是,脑子想一下用什么实现,VC,还是c# ,还是JAVA。VC和C# 如果没有必须用JVM.DLL反向来调一下,比较烦。

 还是用JAVA实现,考虑到使用友好,于是采用SWT,晕倒,还没有开始写,导出可执行JAR,就有16M。于是改用SWING写。


好了,废话不说了,直接上代码了

package com.aua.util;

import java.awt.EventQueue;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import brut.androlib.ApkDecoder;

import com.googlecode.dex2jar.v3.Main;
/**
 *
 * @author crazy_cabbage
 *
 */
public class Dec {

    private JFrame frmAndroid;
    private JFileChooser jFileChooser;
    private JTextField txtApk;
    private JTextField txtOutDir;
    private Executor executor = Executors.newFixedThreadPool(2);
    private boolean flag = false;
    private JLabel lblTime;
    private JLabel lblRemark;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Dec window = new Dec();
                    window.frmAndroid.setVisible(true);
                } catch (Exception e) {
                }
            }
        });
    }

    /**
     * Create the application.
     *
     * @throws UnsupportedLookAndFeelException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws ClassNotFoundException
     */
    public Dec() throws ClassNotFoundException, InstantiationException,
            IllegalAccessException, UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        frmAndroid = new JFrame();
        frmAndroid.setIconImage(Toolkit.getDefaultToolkit().getImage(
                Dec.class.getResource("/com/aua/util/ic_launcher.png")));
        frmAndroid.setTitle("android \u53CD\u7F16\u8BD1\u5DE5\u5177");
        frmAndroid.setBounds(100, 100, 450, 300);
        jFileChooser = new JFileChooser();
        frmAndroid.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmAndroid.getContentPane().setLayout(null);

        JLabel lblApk = new JLabel("APK\u6587\u4EF6:");
        lblApk.setBounds(25, 38, 54, 15);
        frmAndroid.getContentPane().add(lblApk);

        txtApk = new JTextField();
        txtApk.setEditable(false);
        txtApk.setBounds(89, 35, 240, 21);
        frmAndroid.getContentPane().add(txtApk);
        txtApk.setColumns(10);
        lblRemark = new JLabel("");
        lblRemark.setBounds(25, 127, 160, 15);
        frmAndroid.getContentPane().add(lblRemark);

        lblTime = new JLabel("");
        lblTime.setBounds(205, 127, 130, 15);
        frmAndroid.getContentPane().add(lblTime);
        JButton btnApk = new JButton("APK\u6587\u4EF6");
        btnApk.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                jFileChooser.setMultiSelectionEnabled(false);
                jFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                int method = jFileChooser.showOpenDialog(frmAndroid);
                if (JFileChooser.APPROVE_OPTION == method) {
                    String absolutePath = jFileChooser.getSelectedFile()
                            .getAbsolutePath();
                    if (!absolutePath.toLowerCase().endsWith(".apk")) {
                        JOptionPane.showMessageDialog(frmAndroid, "请选择APK文件");
                        return;
                    }
                    txtApk.setText(jFileChooser.getSelectedFile()
                            .getAbsolutePath());
                }

            }
        });
        btnApk.setBounds(339, 34, 93, 23);
        frmAndroid.getContentPane().add(btnApk);

        JLabel lblOutDir = new JLabel("\u8F93\u5165\u76EE\u5F55:");
        lblOutDir.setBounds(25, 72, 54, 15);
        frmAndroid.getContentPane().add(lblOutDir);

        txtOutDir = new JTextField();
        txtOutDir.setEditable(false);
        txtOutDir.setBounds(89, 69, 240, 21);
        frmAndroid.getContentPane().add(txtOutDir);
        txtOutDir.setColumns(10);

        JButton btnOutDir = new JButton("\u8F93\u51FA\u76EE\u5F55");
        btnOutDir.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                jFileChooser.setMultiSelectionEnabled(false);
                jFileChooser
                        .setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int method = jFileChooser.showOpenDialog(frmAndroid);
                if (JFileChooser.APPROVE_OPTION == method) {
                    if (jFileChooser.getSelectedFile().listFiles().length != 0) {
                        JOptionPane.showMessageDialog(frmAndroid, "请选择一个空目录");
                        return;
                    }
                    txtOutDir.setText(jFileChooser.getSelectedFile()
                            .getAbsolutePath());
                }
            }
        });
        btnOutDir.setBounds(339, 68, 93, 23);
        frmAndroid.getContentPane().add(btnOutDir);

        final JButton btnOK = new JButton("\u5F00\u5DE5");
        btnOK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (txtApk.getText().length() == 0) {
                    JOptionPane.showMessageDialog(frmAndroid, "请选择APK文件");
                    return;
                }
                if (txtOutDir.getText().length() == 0) {
                    JOptionPane.showMessageDialog(frmAndroid, "请选择输出目录");
                    return;
                }
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        flag = true;
                        try {
                            executor.execute(new Runnable() {

                                @Override
                                public void run() {
                                    int i = 0;
                                    while (flag) {
                                        i++;
                                        lblTime.setText("已耗时" + i + "秒");
                                        try {
                                            Thread.sleep(1000);
                                        } catch (InterruptedException e) {
                                        }
                                    }
                                }
                            });
                            lblRemark.setText("正在解码资源文件");
                            btnOK.setEnabled(false);
                            btnOK.setText("解码中");
                            ApkDecoder decoder = new ApkDecoder();
                            decoder.setForceDelete(true);
                            decoder.setApkFile(new File(txtApk.getText()));
                            decoder.setOutDir(new File(txtOutDir.getText()));
                            decoder.decode();
                            File src = new File(txtApk.getText());
                            ZipFile zipFile = new ZipFile(src);
                            ZipEntry zipEntry = zipFile.getEntry("classes.dex");
                            InputStream inputStream = zipFile
                                    .getInputStream(zipEntry);
                            FileOutputStream fileOutputStream = new FileOutputStream(
                                    new File(txtOutDir.getText(), "classes.dex"));
                            byte[] b = new byte[1024];
                            int length = -1;
                            while ((length = inputStream.read(b)) != -1) {
                                fileOutputStream.write(b, 0, length);
                            }
                            fileOutputStream.close();
                            lblRemark.setText("正在还原dex 到 classes");
                            Main.doFile(
                                    new File(txtOutDir.getText(), "classes.dex"),
                                    new File(txtOutDir.getText(), "classes.jar"));
                            flag = false;
                        } catch (Exception ex) {
                            JOptionPane.showMessageDialog(frmAndroid, "反编译出错");
                        } finally {
                            lblRemark.setText("");
                            lblTime.setText("");
                            btnOK.setText("开工");
                            btnOK.setEnabled(true);
                            JOptionPane.showMessageDialog(frmAndroid, "反编译成功");
                        }
                    }

                });
            }
        });
        btnOK.setBounds(177, 195, 93, 23);
        frmAndroid.getContentPane().add(btnOK);

    }
}

要点说一下,中途发现一个问题就是 apktools 和dex2jar 的依赖包都用了 commons-io 两者有不兼容,我后来的解决方法是,删了二者中的相关commons-io的类,用上了commons-io 2.0 jar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值