Android apk仿反编译套路(二)

反编译Apk时你是否遇到过下图中的错误,反编译进行到某个dex文件时就报错了。

《Android apk仿反编译套路(二)》 image.png

于是根据错误信息ApkDecoder.decode到apktool源码中查找

            if (hasSources()) {
                switch (mDecodeSources) {
                    case DECODE_SOURCES_NONE:
                        mAndrolib.decodeSourcesRaw(mApkFile, outDir, "classes.dex");
                        break;
                    case DECODE_SOURCES_SMALI:
                        mAndrolib.decodeSourcesSmali(mApkFile, outDir, "classes.dex", mBakDeb, mApi);
                        break;
                }
            }

            if (hasMultipleSources()) {
                // foreach unknown dex file in root, lets disassemble it
                Set<String> files = mApkFile.getDirectory().getFiles(true);
                for (String file : files) {
                    if (file.endsWith(".dex")) {
                        if (! file.equalsIgnoreCase("classes.dex")) {
                            switch(mDecodeSources) {
                                case DECODE_SOURCES_NONE:
                                    mAndrolib.decodeSourcesRaw(mApkFile, outDir, file);
                                    break;
                                case DECODE_SOURCES_SMALI:
                                    mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApi);
                                    break;
                            }
                        }
                    }
                }
            }

从源码中可以看到apktool会先找到classes.dex进行反编译,然后再遍历后缀名为.dex的所有文件进行反编译。

那么只要在apk中添加一个假的.dex文件就能导致apktool反编译失败。

那如何在自己的apk中添加假的dex呢?

  1. 反编译apk

通过以下命令反编译apk

apktool d -s -r xxx.apk
  1. 添加假的dex文件

在反编译结果文件夹中创建一个空文件命名为’classes.dex’(实际上任何名称都行只要后缀名为.dex

  1. 回编译apk

用一下命令回编译apk

apktool b .
  1. apk签名

因为apk反编译之后签名信息会丢失,因此需要重新签名。

可以用jarsigner命令。

这样一个新的apk就出来了,这时可以用apktool再反编译试试,是不是会报错😁

那遇到这种apk该如何正确反编译呢?

简单粗暴的做法:修改apktool源码增加try catch

            if (hasMultipleSources()) {
                // foreach unknown dex file in root, lets disassemble it
                Set<String> files = mApkFile.getDirectory().getFiles(true);
                for (String file : files) {
                    if (file.endsWith(".dex")) {
                        if (! file.equalsIgnoreCase("classes.dex")) {
                            switch(mDecodeSources) {
                                case DECODE_SOURCES_NONE:
                                    mAndrolib.decodeSourcesRaw(mApkFile, outDir, file);
                                    break;
                                case DECODE_SOURCES_SMALI:
                                    // 增加异常捕捉防止反编译dex文件过程出错导致退出程序
                                    try{
                                        mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApi);
                                    }catch (Throwable t){
                                        t.printStackTrace();
                                    }
                                    break;
                            }
                        }
                    }
                }
            }

附:

apktool源码地址:https://github.com/iBotPeaches/Apktool

测试apk下载地址:http://cdn.video4.cn/mock-dex.apk

    原文作者:hellsam
    原文地址: https://www.jianshu.com/p/53552f94502f
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞