26
2017
09

Apk解析之 —— classes.dex

本篇解析classes.dex文件,参考文章:Reference
项目源码:ApkParser

Dex文件结构

文件头 header
索引区 string_ids
type_ids
proto_ids
field_ids
method_ids
数据区 class_defs
data
link_data

一、头部信息Header结构

头部信息除了dex文件的文件信息外,还有文件里其他区域的索引。

字段名 含义 长度
magic dex文件魔数 8B 固定格式:dex\n035\0,035是dex文件格式版本号
checksum 文件校验码 ,使用alder32算法校验文件除去 maigc,checksum 外余下的所有文件区域 ,用于检查文件错误 4B
signature SHA-1算法出去magic,checksum,signature外余下的所有文件区域,用于唯一标识本文件 4B
fileSize Dex 文件的大小 4B
headerSize header 区域的大小,一般固定为0x70常量 4B
endianTag 大小端标签 ,标准.dex文件格式为小端 4B 固定为0x12345678
linkSize 链接数据的大小 4B
linkOff 链接数据的偏移 4B
mapOff map item的偏移地址,该item属于data区里的内容,值要大于等于data_off的大小 4B
stringIdsSize
stringIdsOff
dex中用到的所有的字符串内容的大小和偏移值 4B+4B
typeIdsSize
typeIdsOff
dex中的类型数据结构的大小和偏移值,比如类类型,基本类型等信息 4B+4B
protoIdsSize
protoIdsOff
dex中的元数据信息数据结构的大小和偏移值,描述方法的元数据信息,比如方法的返回类型,参数类型等 4B+4B
filedIdsSize
filedIdsOff
dex中的字段信息数据结构的大小和偏移值 4B+4B
methodIdsSize
methodIdsOff
dex中的方法信息数据结构的大小和偏移值 4B+4B
classDefsSize
classDefsOff
dex中的类信息数据结构的大小和偏移值,这个数据结构是整个dex中最复杂的数据结构 4B+4B
dataSize
dataOff
dex中数据区域的结构信息的大小和偏移值,这个结构中存放的是数据区域,比如我们定义的常量值等 4B+4B

二、string_ids数据结构

头部的stringIdsOff指向了实际的全局String数据区,数据区开始的位置保存了StringDataItem的索引地址数组,每个StringDataItem又包含了String的长度(LEB128编码)和String的内容。这个数据池是全局公用的。

字段名 含义 长度
utf16Size LEB128格式的字符串长度编码 [1,5]B
data 字符串内容 utf16Size

三、type_ids数据结构

这个数据结构中存放的数据主要是描述dex中所有的类型,比如类类型,基本类型等信息。type_ids 区索引了 dex 文件里的所有数据类型 ,包括 class 类型 ,数组类型(array types)和基本类型(primitive types) 。

字段名 含义 长度
descriptorIdx type的字符串表述在string_ids中的下标索引 4B

四、proto_ids数据结构

proto 的意思是 method prototype 代表 java 语言里的一个 method 的原型 。

字段名 含义 长度
shortyIdx method原型的字符串表述在string_ids中的下标索引 4B
returnTypeIdx method原型返回值类型的字符串表述在type_ids中的索引 4B
parametersOff 指向method原型的参数列表type_list,没有参数时值为0

原型用于描述方法的返回参数和入参的组成成分,shorty指向的字符串格式如:返回值+入参列表

// shorty指向的原型字符串,每个类型都是用单字母标识:如L表示类,I标识int,V标识void,Z表示boolean
LI(I)[Landroid/support/v7/widget/Toolbar$SavedState; -> LI
L()[Landroid/view/Display; -> L
VL(Landroid/support/v4/media/MediaBrowserServiceCompat;)V ->VL

五、field_ids数据结构

filed_ids 区里面存放的是dex 文件引用的所有的 field

字段名 含义 长度
classIdx field所属的class类型,指向type_ids中的索引 2B
typeIdx field本身的类型,指向type_ids中的索引 2B
nameIdx field的名称,指向string_ids中的索引 4B

六、method_ids数据结构

method_ids 是索引区的最后一个条目 ,它索引了 dex 文件里的所有的 method.

字段名 含义 长度
classIdx method所属的class类型,指向type_ids的下标索引 2B
protoIdx method的原型,指向proto_ids的下标索引 2B
nameIdx method的名称,指向string_ids的下标索引 4B

七、class_defs数据结构

字段名 含义 长度
class_idx 具体的 class 类型,值是type_ids的index,必须是class类型 4B
access_flags class的访问类型,如public,final,static 4B
superclass_idx superclass的类型,值是type_ids的index 4B
interfaces_off 值是一个偏移地址,指向class的interfaces, 格式为type_list 4B
source_file_idx 源代码文件的信息,指向string_ids的index 4B
annotions_off 值是一个偏移地址,指向的内容是该class的注释 ,位置在data区,格式为annotations_direcotry_item 4B
class_data_off 值是一个偏移地址 ,指向的内容是该class使用到的数据,位置在 data 区,格式为class_data_item 4B
static_value_off 值是一个偏移地址 ,指向 data 区里的一个列表 ( list ) ,格式为 encoded_array_item 4B

7.1 class_def_item -> class_data_item

class_data_item 里存放着本 class 使用到的各种数据

字段名 含义 长度
static_fields_size uleb128
instance_fields_size uleb128
direct_methods_size uleb128
virtual_methods_size uleb128
static_fields 静态成员 sizeof(encoded_field) * static_fields_size
instance_fields 实例成员 sizeof(encoded_field) * instance_fields_size
direct_methods 直接方法 sizeof(encoded_method) * direct_methods_size
virtual_methods 多态方法 sizeof(encoded_method) * virtual_methods_size

7.2 encoded_field

字段名 含义 长度
filed_idx_diff uleb128
access_flags uleb128

7.3 encoded_method

字段名 含义 长度
method_idx_diff uleb128
access_flags uleb128
code_off uleb128

7.4 code_item

字段名 含义 长度
registers_size 本段代码使用到的寄存器数目 2B
ins_size method传入参数的数目 2B
outs_size 本段代码调用其它method 时需要的参数个数 2B
tries_size try_item 结构的个数 2B
debug_info_off 指向本段代码的 debug 信息存放位置 ,是一个 debug_info_item 结构 4B
insns_size 指令列表的大小 ,以 16-bit 为单位 。 insns 是 instructions 的缩写 4B
insns 指令列表 2B*n

7.5 interfaces_off -> type_list

字段名 含义 长度
size 列表长度 4B
type_idx type参数在type_ids中的索引 2B * size

八、END

.

上一篇:Genymotion错误:An error occured while deploying the file. 下一篇:Fresco解析 三