APK的全称是AndroidPackage,它是Android安装包。APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以看到Dex文件,Dex是Dalvik VM executes的全称,即Android Dalvik执行程序,并非Java ME的字节码而是Dalvik字节码。
下面以HelloWorld为例讲解Android应用程序的文件结构及打包过程。
现在编写一个HelloWorld应用程序已经变得非常简单的,在eclipse集成开发环境中只需要点击下一步基本就可以完成此应用程序。图1.1即为由eclipse集成开发环境生成的HelloWorld应用程序的文件结构图。
图1.1 HelloWorld文件结构图
其中,
Src java源文件目录
Gen 自动生成的目录,其中包括了著名的R.java
Android 2.3.3 该应用程序依赖的android SDK包。
Assets 存放原生文件,这个目录保存的文件可以打包在程序里。和res的不同点是,android不为assets下的文件生成ID,如果使用assets下的文件,需要指定文件的路径和文件名。
Bin Java编译输出的路径
Res 存放程序所需要的资源文件,也就是非Java的文件。常见的目录有,
(1)res/animator/ :XML文件,定义动画属性
(2)res/anim/ :XML文件,它们被编译进逐帧动画(frame by frame animation)或补间动画(tweened animation)对象
(3)res/color/:XML文件,定义颜色状态的列表
(4)res/layout/:存放被编译为屏幕布局(或屏幕的一部分)的XML文件
(5)res/menu/:XML文件,用来定义应用的菜单
(6)res/drawable/:存放图片文件,如.png, .jpg, .gif等。放在这里的图像资源可能会被aapt(android assert packaging tool,android资源打包工具)自动地进行无损压缩优化。如果你不想图片被压缩改变,请把图像文件放在 res/raw/目录下,这样可以避免被自动优化。
(7)res/raw/:直接复制到设备中的任意文件,它们无需编译
(8)res/values/:存放可以被编译成很多种类型的资源文件, XML 格式的。常见的文件有:
array.xml :定义数组
colors.xml :定义color drawable和颜色的字符串值。
dimens.xml : 定义尺寸值(dimension value)。
strings.xml :定义字符串(string)值。
styles.xml:定义样式(style)对象。
(9)res/xml/:任意的XML文件,在运行时可通过调用Resources.getXML()读取。
AndroidManifest.xml
这个清单给Android系统提供了关于这个应用程序的基本信息,系统在运行任何程序代码之前必须知些信息。AndroidManifest.xml主要包含以下功能:
(1)命名应用程序的 Java 包,这个包名用来唯一标识应用程序
(2)描述应用程序的组件:活动,服务,广播接收者,以及组成应用程序的内容提供器;对实现每个组件和公布其能力(比如,能处理哪些意图消息)的类进行命名。这些声明使得 Android系统了解这些组件以及在什么条件下可以被启动;
(3)决定应用程序组件运行在哪个进程里面
(4)声明应用程序所必须具备的权限,用以访问受保护的部分 API,以及和其它应用程序交互;
(5)声明应用程序其他的必备权限,用以组件之间的交互;
(6)列举测试设备Instrumentation类,用来提供应用程序运行时所需的环境配置和其他信息,这些声明只是在开发和测试阶段存在,发布前将被删除
(7) 声明应用程序所要求的Android API的最低版本级别;
(8)列举application所需要链接的库
Proguard-project.txt
Android代码混淆器,用于加大反编译的难度。详细描述请见
http://developer.android.com/tools/help/proguard.html
Project.properties
定义一些项目的基本属性。
图1.2为Android应用程序打包流程图。从图中我们可以看到,
a. Java源文件通过javac编译成class, 然后class通过dx.bat生成虚拟机运行的二进制程序。
b. 资源文件通过appt打包。
c. 打包好的源文件及资源文件通过apkbuilder生成未签名的APK。
d. 通过keytool生成key
e. Jarsigner为未签名的APK生成签名。
至此,整个APK打包过程已经完成。
想要探究APK内部结构,就不得不对其进行逆向工程了。图2.1为Android应用程序逆向工程流程图。正如本文开头所述,APK文件其实是zip格式,因此可以直接通过unzip工具进行解压。解压后主要包含资源文件及dex,注意这些资源文件都是压缩过的,需要通过特殊工具解析才可使用。
从图2.1我们可以看到,实际上可以通过apktool + dex2jar + xjad/JD-GUI实现对APK的逆向工程。下面我们就一一讲解各项工具的使用方法, 解开APK的今生之谜。
图2.1 Android应用程序逆向工程流程图
APK文件其实是zip格式,但后缀名被修改为apk,通过UnZip解压后,可以得到APK文件结构。
下面我们就开始激动人心的APK逆向工程吧。
1.2.1 资源文件
如果直接解压APK文件,那么对应的资源文件都是经过某种格式压缩过的。因此我们需要一些工具来解析这些文件。Apktool是一个非常棒的解析资源文件的工具,实际上它还可以将dex文件转换成smoli格式的文件。
Ø Apktool
官网: http://code.google.com/p/android-apktool/
在apktool官网上,有两个包需要下载,如果在windows上反编译,下载apktool-install-windows-xx.tar.bz2及apktoolxx.tar.bz2即可。如果在linux上反编译,则下载apktool-install-linux-xx.tar.bz2及apktoolxx.tar.bz2。
apktool运行格式:
apktool d xxx.apk output 反编译xxx.apl到文件夹output
apktool b output 从文件夹output重构apk,输出到output/dist/out.apk
反编译之后的文件如下所示。其中xml文件都已经成功反编译,而dex文件被反编译成smali格式。这种语法很难读懂,我们可以通过其他工具来反编译dex文件。在apktool的官网上,我们看到有如果通过smali来debug apk。看上去还有点意思。http://code.google.com/p/android-apktool/wiki/SmaliDebugging
1.2.2 可执行文件
经过unzip解压之后的APK会生成一个class.dex文件。
Ø dex2jar
官网:https://code.google.com/p/dex2jar/
运行 dex2jar.bat classes.dex
生成 classes_dex2jar.jar
Ø JD-GUI
官网:http://java.decompiler.free.fr/?q=jdgui
用JD-GUI打开dex2jar生成的classes_dex2jar.jar后,就可以看到java源文件啦。如下图所示。
Ø Apkdb
官网:http://code.google.com/p/android-apkdb/
《Android APK+Dex文件反编译及回编译工具》简称:APKDB。是一款,针对Android OS系统APK程序,直接反编译修改的工具。APKDB集合了当今最强悍,最犀利的APK及Dex文件编译工具;正常安装后,它直接在【鼠标右键】创建快捷菜单;非常方便汉化工作者,对APK或Dex文件进行简易的反编译回编译操作。
by JHJ