Android APK 反编译实践

apk是安卓工程打包的最终形式,将apk安装到手机或者模拟器上就可以使用APP。反编译apk则是将该安卓工程的源码、资源文件等内容破解出来进行分析。客户端QA可能会遇到的问题是,本地测试包与正式发布的apk包之间可能存在差异(debug与release)。如果能够进行最终上线前的apk反编译,一方面可以校验apk是否有遗漏的Jar包或者资源文件,另一方面也可以简要核对本版本apk的基本信息是否正确。可加入产品上线前最终上线清单确认的环节中。本文主要介绍了apk反编译的基本原理和主要方法,最后介绍了目前比较成熟的反编译工具。

一、APK反编译基本原理

1.APK分析

apk文件的本质是压缩文件,我们将apk文件修改后缀名为zip或者rar等,可以直接解压缩查看apk文件夹。下图即为一个基本的apk文件夹结构图。


我们简要看下每个文件夹和文件里都有什么内容:

  • assets文件夹:原始资源文件夹,对应着Android工程的assets文件夹,一般用于存放原始的图片、txt、css等资源文件。
  • lib:存放应用需要的引用第三方SDK的so库。比如一些底层实现的图片处理、音视频处理、数据加密的库等。而该文件夹下有时会多一个层级,这是根据不同CPU 型号而划分的,如 ARM,ARM-v7a,x86等。
  • META-INF:保存apk签名信息,保证apk的完整性和安全性。
  • res:资源文件夹,其中的资源文件包括了布局(layout),常量值(values),颜色值(colors),尺寸值(dimens),字符串(strings),自定义样式(styles)等。
  • AndroidManifest.xml文件:全局配置文件,里面包含了版本信息、activity、broadcasts等基本配置。不过这里的是二进制的xml文件,无法直接查看,需要反编译后才能查看。
  • classes.dex文件:这是安卓代码的核心部分,,dex是在Dalvik虚拟机上可以执行的文件。这里有classes.dex和classes2.dex两个文件,说明工程的方法数较多,进行了dex拆分。
  • resources.arsc文件:记录资源文件和资源id的映射关系。

直接查看apk压缩文件,只有assets可以直接查看,我们可以校验其中是否已加入必需的资源文件。但是对于版本的基本情况、所需的JAR包等都是无法直接查看的,需要进行apk反编译处理。了解apk的反编译原理,需要从apk打包原理讲起。

2.从APK打包讲起

使用IDE进行安卓开发,便捷的打包调试使得打包的很多细节都忽略了,安卓官网给出了apk打包的基本流程图,图中红框是我对打包流程几个主要模块的划分:

我们从中梳理出apk打包的基本流程模块如下:

  1. 资源处理
    这一过程中主要使用appt工具进行资源文件的处理,分析AndroidManifest.xml中的资源文件,生成R.java和resources.arsc文件;aidl工具负责处理aidl文件,生成对应的java接口文件。
  2. 代码编译
    将上一过程中产生的R.java、java接口文件以及工程源代码一起通过Java Compiler编译成.class文件,打成Jar包(这部分可以加入代码混淆),然后与第三方库的Jar包一起通过dx工具转换成.dex文件。
    通过apkbuilder工具将aapt生成的resources.arsc、classes.dex(可能多个)、其他的资源一块打包生成未经签名的apk文件。
  3. 添加签名
    通过Jarsigner对生成的未签名的apk进行签名。
    再通过zipalign对签名后的apk进行对其处理,使apk中所有资源文件距离文件起始偏移为4字节的整数倍,从而在通过内存映射访问apk文件时会更快。

3.APK反编译原理

通过回顾apk的打包原理,反编译要做的事情也就明了了。反编译要做的,一是要将apk里的dex文件转换成Jar包,再通过工具查看编译前的java源文件。二是通过工具查看apk里对应的AndroidManifest.xml、resources.arsc、res各布局文件等二进制文件。反编译所需要的工具主要有以下几个:

二、APK反编译实践

1.使用dex2jar将dex文件转换成Jar包

在Mac上下载的dex2jar-2.0.zip包直接解压缩即可,关键需要用到的文件是d2j-dex2jar.sh和d2j-dex2jar_invoke.sh,需要对这两个文件先添加可执行权限。然后将目标apk改为zip后缀,解压缩直接拿到其中的dex文件。在终端输入命令:

./d2j-dex2jar/d2j-dex2jar.sh classes.dex

注意要输入classes.dex的正确路径。
命令结束后会在当前目录下生成classed-dex2jar.jar文件。如下图所示:



ps:如果apk的方法数超过了65535,会生成多个dex文件,反编译的话需要对这多个dex文件均进行转换Jar包处理。

2.使用jd-gui将Jar包文件反编译成java源文件
jd-gui下载解压后,直接打开文件夹里面的JD-GUI,即可打开图形化界面。将我们上一个步骤生成的classes-dex2jar.jar直接拖动进入界面中,就可以看到反编译之后的源码结构了。


ps:这里有时候会看到诸如a.a.a、b等字母标示的包名、类名或者方法名,这是由于在某些apk打包的时候进行代码混淆导致的。使用反编译工具只能看到混淆之后的代码结构,真正未混淆前的源码还需要结合mapping.txt文件进行分析。mapping.txt文件里即标注出了代码混淆前后的文件名称对应关系。

3.使用apktool工具查看apk里的二进制文件
下载下来apktool并解压缩后,调用java命令执行,命令如下:

java -jar apktool.jar d yourApkName.apk

命令执行完后,会在当前目录下新增yourApkName文件夹,其中可以看到可读的AndroidManifest.xml、res目录下的各布局文件、assets文件夹等。



original文件夹是原始的AndroidManifest.xml文件,res文件夹是反编译出来的资源,smali文件夹是反编译出来的代码。注意,smali是有点类似于汇编的语法,是Android虚拟机所使用的寄存器语言。

三、其他APK反编译工具

以上是apk反编译常用的主要工具和方法,现在也有一些工具可以将这些反编译步骤全部集成起来,常用的有:

1.Android-classyshark
下载地址:https://github.com/google/android-classyshark/releases,下载下来之后是一个可执行的jar文件,在终端执行java -jar classyshark.jar即可打开图形化界面。在打开的图形操作界面中拖入待目标apk,即可展示出反编译之后的结果。

点击上方的“Methods count”还能看到各个类中具体的方法数。


2.Android Studio 2.2的APK Analyzer
Android Studio 2.2版本新增了APK Analyzer功能,使用方法很简单,只需要将目标apk拖入到Android Studio 2.2中即可。


功能十分强大,可以直接将APK全部反编译出来,在Android Studio界面上可以直接看到apk版本的信息,直接查看AndroidManifest.xml、R.java等文件。点击classes.dex可以直接查看反编译之后的代码结构。可以说是集合了apktool、dex2jar、jd-gui等反编译工具的全部功能,十分便捷。

上述是比较常见且较为成熟的apk反编译工具,但是稍有遗憾的是,以上工具均只能反编译至混淆后的代码,如何结合mapping.txt恢复成源代码,还没有发现比较好的工具。

四、结语

在日常安卓端产品测试过程中,曾经出现过的问题是本地测试打包与上线打包有差异,原因可能是开发误以为某些jar包和资源文件只是本地测试需要,上线不需要,也可能是本地测试打包与上线打包的build types不同,导致本地测试通过,而上线后出现了异常情况。这类问题测试的难点在于,待上线的apk包对于某些情况无法经过QA实时校验、缺少的jar包和资源文件并不会导致回归测试的功能异常等。为了避免这种问题,对于apk正式上线前的上线清单,可考虑加入待发布apk的反编译资源包确认。QA可仔细核验最终待发布的apk,可以通过反编译的手段进一步对apk进行分析,查看是否新增的jar包和资源文件、so文件等均没有遗漏,回归测试功能点也没有异常,才能正式上线。

总之,产品发布是一件需谨慎对待的事情,增加对待上线apk的反编译分析,一定程度上可以对产品质量做最后一道把关。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容