Android逆向基础----APK文件结构
参考这个博客
http://www.cnblogs.com/wangtianxj/archive/2010/06/13/1757639.html
http://blog.csdn.net/bupt073114/article/details/42298337
APK文件结构:
AndroidManifest.xml 配置清单
META-INF 签名
assets 资源
classes.dex java经过源码编译后生成的java字节码文件
res 资源库
lib native 动态库 so
smali classes.dex
resources.arsc 记录这些ID和资源文件位置对应关系的文件
apktool.yml 重新打包必须文件
META-INF目录:存放的是签名信息,用来保证apk包的完整性和系统的安全。
在编译生成一个api包时,会对所有要打包的文件做一个校验计算,并把计算结果放在META-INF目录下。在安装时,如果校验结果与META-INF下的内容不一致,系统就不会安装这个apk。保证了apk包里的文件不能被随意替换。
META-INF目录下包含的文件有CERT.RSA,CERT.DSA,CERT.SF和MANIFEST.MF。
CERT.RSA |
是开发者利用私钥对APK进行签名的签名文件 |
CERT.SF,MANIFEST.MF |
记录了文件中文件的SHA-1哈希值 |
assets目录:用于存放需要打包到APK中的静态文件
assets目录支持任意深度的子目录,用户可以根据自己的需求任意部署文件夹架构。
而且res目录下的文件会在.R文件中生成对应的资源ID,assets不会自动生成对应的ID,访问的时候需要AssetManager类。
lib目录:这里存放应用程序依赖的native库文件,一般是用C/C++编写,这里的lib库可能包含4中不同类型,根据CPU型号的不同,大体可以分为ARM架构,ARM-V7a架构,MIPS架构和X86架构。
不同的CPU架构对应着不同的目录,目前市场上使用的移动终端大多是基于ARM或者ARM-V7a架构的,X86和MIPS架构的移动智能终端比较少,这四个目录要根据CPU的架构来选,而市面上ARM架构的手机占大多数,所以一般的APK只包含ARM和ARM-V7a的so。
res目录:res是resource的缩写,这个目录存放资源文件,存在这个文件夹下的所有文件都会映射到Android工程的.R文件中,生成对应的ID,访问的时候直接使用资源ID即R.id.filename,res文件夹下可以包含多个文件夹。
文件名 |
存储内容 |
anim |
存放动画文件; |
drawable |
目录存放图像资源; |
layout |
目录存放布局文件; |
values |
目录存放一些特征值; |
colors.xml |
存放color颜色值; |
dimens.xml |
定义尺寸值; |
string.xml |
定义字符串的值; |
styles.xml |
定义样式对象; |
xml |
文件夹存放任意xml文件,在运行时可以通过Resources.getXML()读取; |
raw |
是可以直接复制到设备中的任意文件,他们无需编译。 |
AndroidManifest.xml:是Android应用程序的配置文件,是一个用来描述Android应用“整体资讯”的设定文件, Android系统可以根据这个“自我介绍”完整地了解APK应用程序的资讯,每个Android应用程序都必须包含一个AndroidManifest.xml文件,且它的名字是固定的,不能修改。我们在开发Android应用程序的时候,一般都把代码中的每一个Activity,Service,Provider和Receiver在AndroidManifest.xml中注册,只有这样系统才能启动对应的组件,另外这个文件还包含一些权限声明以及使用的SDK版本信息等等。程序打包时,会把AndroidManifest.xml进行简单的编译,便于Android系统识别,编译之后的格式是AXML格式,如下图1所示:
图1 AXML格式
axml头 |
其中的axml头是固定标识axml文件的,其值固定时0x00080003。 |
axml文件长度 |
标识axml文件的大小。 |
StringDataSegment |
xml文件中所有字符串类型保存在此。 |
ResourceIdSegment |
xml文件中声明的资源文件ID保存于此。 |
XmlContentSegment |
是xml的内容段,按照xml文件中的结构依次排开,保存xml的数据内容。 |
classes.dex:
传统的Java程序,首先先把Java文件编译成class文件,字节码都保存在了class文件中,Java虚拟机可以通过解释执行这些class文件。而Dalvik虚拟机是在Java虚拟机进行了优化,执行的是Dalvik字节码,而这些Dalvik字节码是由Java字节码转换而来,一般情况下,Android应用在打包时通过AndroidSDK中的dx工具将Java字节码转换为Dalvik字节码。dx工具可以对多个class文件进行合并,重组,优化,可以达到减小体积,缩短运行时间的目的。dx工具的转换过程如图2所示:
图2 dx工具把.class文件转换成dex文件
dx工具把每个.class文件的每个区域的内容进行去重,重组,优化重排后生成dex文件,生成的dex文件可以在Dalvik虚拟机执行,且速度比较快。
resources.arsc:用来记录资源文件和资源ID之间的映射关系,用来根据资源ID寻找资源。Android的开发是分模块的,res目录专门用来存放资源文件,当在代码中需要调用资源文件时,只需要调用findviewbyId()就可以得到资源文件,每当在res文件夹下放一个文件,aapt就会自动生成对应的ID保存在.R文件,我们调用这个ID就可以,但是只有这个ID还不够,.R文件只是保证编译程序不报错,实际上在程序运行时,系统要根据ID去寻找对应的资源路径,而resources.arsc文件就是用来记录这些ID和资源文件位置对应关系的文件。