APK反编译

前言

在学习安卓开发的时候,我们都希望向优秀的应用学习设计思路,看看别人在实现一个功能的时候是怎么做的。但是没有文档、没有源代码,只能感到遗憾了。不过有的时候,我们也可以通过反编译这些应用,获得更多的信息。

这里我们将介绍反编译安卓应用的原理和方法,希望大家通过这些介绍更佳深刻的理解APK的结构,每个模块的功能,通过反编译的部分代码,参考别人的开发思路,帮助我们更好的提高应用开发技术。不过反编译技术也会被作恶的人利用,窜改设计,加入恶意代码,所以这里我们只介绍如何尽可能的还原代码设计,而跳过代码的重组、修改、打包。

本文针对的读者是:

  1. 对安卓开发有初步认识的开发者;
  2. 向学习和借鉴优秀应用设计方式的开发者;

在开始以前,假设各位已经做好了如下准备:

  • 已经搭建好了的安卓软件开发平台
  • 待反编译的APK包

本文将介绍到:

  1. APK的包结构;
  2. 编译与反编译的概念;
  3. 反编译资源文件和java源代码

第1节 APK包的结构

Android应用存在的实体形式是一个后缀为apk的安装包,例如“微信.apk” “QQ.apk”。将这个安装包放入到Android系统后,系统就可以启动运行它了。

apk安装包实际上是一个zip压缩包。我们用解压软件可以将它解压,解压后可以看到如下图的文件结构和目录结构。

1.1 classes.dex

classes.dex就是程序中java文件被编译后生成的字节码。字节码可以在Android系统的虚拟机(VM)运行。我们说的运行一个安卓程序,其实就是运行这个程序的字节码。

1.2 res

res中存放的的这个应用会使用到的资源文件,例如字符串、图片、界面布局等等。它的目录结构与Android Studio中我们看到的项目工程的res目录一样。这里面的xml文件内容都是被编译器编译过的,实际它们上已经变成了二进制文件,不再是文本文件了。

1.3 assets

asset目录下存放的是不会被编译器处理的文件,一般是一些资源性质的文件,这些文件放进去是什么样,被打包后还是什么样。需要注意的是,asset目录和res目录都可以存放资源,只是前者不被编译器处理,后者会被编译器再转化一次。

1.4 AndroidManifest

AndroidManifest.xml也是被编译器处理过的文件,也是二进制文件,不再是文本文件。

1.5. libs目录

libs目录下存放的是APK使用的库文件--so文件。so文件是c++或者c语言编写后通过编译器生成的。有的应用会使用到so文件,例如微信。使用so文件的应用会通过java,调用c++语言实现的功能。我们暂时把目光投放在纯Java开发应用上,以后再来讲解Java调用c++开发的方式。

因为不是所有的APK都会使用库文件。所以不会有libs目录。

1.6 resources.arsc

resources.arsc文件,用来描述那些具有ID值的资源的配置信息,它的内容就相当于是一个资源索引表。

第2节 APK包反编译

被编译器处理过的代码和资源已经打包成了APK,有的甚至被转化成了二进制文件。但是我们也有一些方法,把这些编译过的内容给变回原来的样子,这个过程叫做-反编译。

反编译分为两个部分:一个是资源文件,一个是java文件。so文件是c++编译的结果,可以认为是不可反编译的(反编译成汇编指令,估计大部分人也看不懂)。

2.1 反编译资源文件

APK tool是反编译的有力工具,据说是谷歌提供的官方的反编译工具,可以把APK目录解包,资源文件全部还原成编译前的样子,而dex文件反编译成smail格式的文件(而不是我们希望的java原文件)。smail格式文件是安卓系统的虚拟机执行时使用的语法,我们不会去讲解这部分内容。

2.1.1 工具准备

  1. APK tool的官网下载APKTool的最新版本;

  2. 在官网下载与APKTool配套的脚本文件-apktool.bat,其内容如下;

  3. 将下载的jar包重命名为APKTool.jar,与脚本文件一起放到你希望存放的目录下,例如D:\Work\apktool;

如果无法访问官网下载,请上安豆网,下载最新的版本。

2.1.2 反编译资源

接下来开始使用APKTool,

  1. 启动cmd命令行窗口,进入apktool目录;
  2. 输入apktool d D:\Test.apk,开始反编译Test.apkapktool d后面需要跟上要反编译的APK文件路径;

  3. 编译的结果就在cmd命令行窗口启动的位置下,反编译的目录结构如下,

现在打开res目录下的资源都被还原了,打开后就能看到原始的设计;而java源码被反编译成了smali格式的文件。

2.2 反编译java源代码

要查看java源码,有三个方式:

  1. 把dex文件转换成smail文件,然后用专门的工具将smail翻译成java;
  2. 把dex文件转换成java的通用编译格式class文件,然后用专门的工具将class翻译成java;
  3. 把dex文件转换成jar文件,然后用专门的工具将jar翻译成java;

这里我们采用第三种方法。

2.2.1 工具准备

首先准备反编译用的工具。

  1. 在官网下载dex2jar工具,它可以把APK中的dex文件转化成jar文件;
  2. 下载完成后,将压缩包解压,放到你希望存放的目录下,例如D:\Work\dex2jar;

  3. 在官网下载JD-GUI,它可以查看jar文件的java源码;

  4. 下载完成后,将压缩包解压,放到你希望存放的目录下,例如D:\Work\jd-gui;

至此,java源码的反编译工具就安装并设置完成了。
如果无法访问官网下载,请上安豆网下载,那里将这几个工具整体打包,方便大家使用。

2.2.2 反编译代码

接下来开始使用反编译工具,

  1. APK文件后缀名改为zip,解压,找到Android软件安装包中的class.dex

  2. 用dex2jar工具将classes.dex生成jar文件;启动cmd命令行窗口,输入d2j-dex2jar D:\classes.dex,开始反编译classes.dexd2j-dex2jar后面需要跟上要反编译的dex文件路径;

    结果生成了classes-dex2jar.jar文件;

  3. 进入JD-GUI目录,运行JD-GUI工具,打开上面的生成的jar文件,即可看到java源代码。

结束

通过上面的介绍,我们就能反编译APK的资源和java源码了。
有的APK还包含了二进制so库文件。不过这里并不能反编译二进制so库文件。so文件是c或者c++代码通过编译器获得的,并不在我们讨论的反编译当中。

反编译APK只是为了我们学习、参考别人的优秀设计,可千万别用它干坏事啊!


/**************************************************************************/
* 版权声明
* 本教程只在CSDN安豆网发布,其他网站出现本教程均属侵权。
/
**************************************************************************/