Android Dex文件结构解析

Java源文件通过Java编译器生成CLASS文件,再通过dx工具转换为classes.dex文件。
DEX文件从整体上来看是一个索引的结构,类名、方法名、字段名等信息都存储在常量池中,这样能够充分减少存储空间,相较于Java字节码文件更适合手机设备。

DEX文件的相关结构声明定义在/dalvik/libdex/DexFile.h文件中,下面我们先来看一下DEX文件中使用到的数据结构。

表1 dex文件使用到的数据结构
类型 含义
u1 等同于uint8_t,表示1字节的无符号数
u2 等同于uint16_t,表示2字节的无符号数
u4 等同于uint32_t,表示4字节的无符号数
u8 等同于uint64_t,表示8字节的无符号数
sleb128 有符号LEB128,可变长度1~5字节
uleb128 无符号LEB128,可变长度1~5字节
uleb128p1 无符号LEB128加1,可变长度1~5字节

DEX文件的基本结构如下图所示:

header
string_ids
type_ids
proto_ids
field_ids
method_ids
class_def
data
link_data
图1 DEX文件结构

1. header(基本信息)

header是DEX文件头,包含magic字段、alder32校验值、SHA-1哈希值、string_ids的个数以及偏移地址等。DEX文件的头结构很固定,占用0x70个字节,具体定义代码如下所示(摘自DexFile.h):

/*
 * Direct-mapped "header_item" struct.
 */


struct DexHeader {
    u1  magic[8];           /* includes version number */  
    u4  checksum;           /* adler32 checksum */  
    u1  signature[kSHA1DigestLen]; /* SHA-1 hash */
    u4  fileSize;           /* length of entire file */
    u4  headerSize;         /* offset to start of next section */
    u4  endianTag;
    u4  linkSize;
    u4  linkOff;
    u4  mapOff;
    u4  stringIdsSize;
    u4  stringIdsOff;
    u4  typeIdsSize;
    u4  typeIdsOff;
    u4  protoIdsSize;
    u4  protoIdsOff;
    u4  fieldIdsSize;
    u4  fieldIdsOff;
    u4  methodIdsSize;
    u4  methodIdsOff;
    u4  classDefsSize;
    u4  classDefsOff;
    u4  dataSize;
    u4  dataOff;
};

magic[8]:共8个字节。目前为固定值dex\n035。

checksum:文件校验码,使用alder32算法校验文件除去magic、checksum外余下的所有文件区域,用于检查文件错误。

signature:使用 SHA-1算法hash除去magic,checksum和signature外余下的所有文件区域 ,用于唯一识别本文件 。

fileSize:DEX文件的长度。

headerSize:header大小,一般固定为0x70字节。

endianTag:指定了DEX运行环境的cpu字节序,预设值ENDIAN_CONSTANT等于0x12345678,表示默认采用Little-Endian字节序。


linkSizelinkOff:指定链接段的大小与文件偏移,大多数情况下它们的值都为0。link_size:LinkSection大小,如果为0则表示该DEX文件不是静态链接。link_off用来表示LinkSection距离DEX头的偏移地址,如果LinkSize为0,此值也会为0。

mapOff:DexMapList结构的文件偏移。

stringIdsSizestringIdsOff:DexStringId结构的数据段大小与文件偏移。

typeIdsSizetypeIdsOff:DexTypeId结构的数据段大小与文件偏移。

protoIdsSizeprotoIdsSize:DexProtoId结构的数据段大小与文件偏移。

fieldIdsSizefieldIdsSize:DexFieldId结构的数据段大小与文件偏移。

methodIdsSizemethodIdsSize:DexMethodId结构的数据段大小与文件偏移。

classDefsSizeclassDefsOff:DexClassDef结构的数据段大小与文件偏移。

dataSizedataOff:数据段的大小与文件偏移。


下面我们来看某apk中classes.dex的解析结果,确实与上面的结构一致:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值