1.Android apk文件结构

Android的apk文件相当于一个压缩文件,解压apk文件后目录下文件大致如下:

android

其中,META-INF文件夹一般存放apk的签名文件,res文件夹存放资源文件,AndroidManifest.xml是程序的全局配置文件,classes.dex是Dalvik下的可执行程序,resources.arsc是编译后的二进制资源文件。要想实现对apk文件的加壳脱壳首先得熟悉dex文件的结构,接下来就一步步的分析并熟悉dex文件。

2.dex文件

Dex(Dalvik VM executes)即Anroid Dalvik虚拟机下的可执行程序,由Dalvik字节码组成,Dex文件的结构比较紧凑,但是还可以将其进一步优化成ODEX文件。Dex文件结构如下:

dex

 

本文主要分析dex文件头部,dex文件头各结构如下:

字段名称偏移值长度数据类型描述
magic0x04ubyte[4]魔数用来标识dex文件
dex\n
version0x44ubyte[4]版本号,有035\0,036\0两种
checksum0x84uint确保dex文件没有被损坏
signature0xC20ubyte[20]用SHA-1算法生成的签名
file_size0x204uint文件的总大小
header_size0x244uint头部大小,固定为0x70字节
endian_tag0x284uint标识是大顶端还是小顶端
link_size0x2C4uint连接段的大小,为0表示不是静态链接
link_off0x304uint连接段从文件头部开始的偏移值
map_off0x344uint表示map数据离文件开头的偏移
string_ids_size0x384uint字符串地址列表中元素的个数
string_ids_off0x3C4uint字符串列表离文件头的偏移
type_ids_size0x404uint类型列表中类型的个数
type_ids_off0x444uint类型列表离文件头的偏移
proto_ids_size0x484uint原型列表里原型的个数
proto_ids_off0x4C4uint类型列表离文件头的偏移
field_ids_size0x504uint字段列表中字段个数
field_ids_off0x544uint字段列表离头文件的偏移
method_ids_size0x584uint方法列表中方法个数
method_ids_off0x5C4uint方法列表离文件头的偏移
class_defs_size0x604uint类定义列表中类的个数
class_defs_off0x644uint类定义列表离文件头的偏移
data_size0x684uint数据段的大小,必须以4字节对齐
data_off0x6C4uint数据段里文件头的偏移

 3.实例解析

使用bless打开一个dex文件,看看头部的几个关键字段:首先是dex文件的魔数dex\n

dex2

16进制0A对应的ascii码即是换行键\n。接下来看看文件总大小字段,偏移值为0x20

dex4

由于文件大小是uint类型的数据,而该类型在大顶端和小顶端的机器上表示顺序相反,这时候endian_tag字段就很关键了

dex5

标准的dex格式是按照小顶端来存储这个字段(字段值为0x12345678),如果这个dex文件(小顶端机器编译)放在另一台小顶端机器,这个字段也能被解释成0x12345678,但是如果是在大顶端机器上解释这个字段,则会将该字段解释成为0x78563412;若在大顶端机器上编译,那么应该将这个字段的值设为0x78563412,这样才能保证在其他机器上能被正确解释。下面这张图能让你更加清晰的认识大小顶端的区别:

da

所以在判断完endian_tag字段后就能正确的解析uint类型的值了。由于本机是小顶端机器,所以file_size字段中的 B0 2B 00 00 被解释成0x2BB0(11184),查看文件属性文件大小肯定也为11184:

dex7

dex文件头部大小固定为0x70,再下来就是各类表的大小和离文件头的偏移,这些比较容易理解,就不多说了。

4.参考文献

http://www.verydemo.com/demo_c131_i72724.html

http://www.sanwho.com/19.html

http://bbs.pediy.com/showthread.php?p=1128514

观看更多有关 的文章?

*

+
跳转到评论