Android逆向基础----APK文件结构

时间:2021-12-01 12:11:18

参考这个博客

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和资源文件位置对应关系的文件。