> For the complete documentation index, see [llms.txt](https://jiek.gitbook.io/android/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jiek.gitbook.io/android/dex.md).

# dex

Mac下可以借助[Hex Fiend](http://ridiculousfish.com/hexfiend/)查看文件头信息。

## 文件头(File Header)

Dex文件头主要包括校验和以及其他结构的偏移地址和长度信息。(20170301) 官方说明 [.dex Format](https://source.android.com/devices/tech/dalvik/dex-format.html)

| 字段名称              | 偏移值  | 长度 | 描述                                                           |
| ----------------- | ---- | -- | ------------------------------------------------------------ |
| magic             | 0x0  | 8  | 'Magic'值，即魔法字段，格式如”**dex/n035/0**”，其中的035表示结构的版本。            |
| checksum          | 0x8  | 4  | 校验码。                                                         |
| signature         | 0xC  | 20 | SHA-1签名。                                                     |
| file\_size        | 0x20 | 4  | Dex文件的总长度。                                                   |
| header\_size      | 0x24 | 4  | 文件头长度，**009版本=0x5C** , **035版本=0x70**。                       |
| endian\_tag       | 0x28 | 4  | 标识字节顺序的常量,根据这个常量可以判断文件是否交换了字节顺序,缺省情况&#x4E0B;**=0x78563412**。 |
| link\_size        | 0x2C | 4  | 连接段的大小，如果为0就表示是静态连接。                                         |
| link\_off         | 0x30 | 4  | 连接段的开始位置，从本文件头开始算起。如果连接段的大小为0，这里也是0。                         |
| map\_off          | 0x34 | 4  | map数据基地址。                                                    |
| string\_ids\_size | 0x38 | 4  | 字符串列表的字符串个数。                                                 |
| string\_ids\_off  | 0x3C | 4  | 字符串列表表基地址。                                                   |
| type\_ids\_size   | 0x40 | 4  | 类型列表里类型个数。                                                   |
| type\_ids\_off    | 0x44 | 4  | 类型列表基地址。                                                     |
| proto\_ids\_size  | 0x48 | 4  | 原型列表里原型个数。                                                   |
| proto\_ids\_off   | 0x4C | 4  | 原型列表基地址。                                                     |
| field\_ids\_size  | 0x50 | 4  | 字段列表里字段个数。                                                   |
| field\_ids\_off   | 0x54 | 4  | 字段列表基地址。                                                     |
| method\_ids\_size | 0x58 | 4  | 方法列表里方法个数。                                                   |
| method\_ids\_off  | 0x5C | 4  | 方法列表基地址。                                                     |
| class\_defs\_size | 0x60 | 4  | 类定义类表中类的个数。                                                  |
| class\_defs\_off  | 0x64 | 4  | 类定义列表基地址。                                                    |
| data\_size        | 0x68 | 4  | 数据段的大小，必须以4字节对齐。                                             |
| data\_off         | 0x6C | 4  | 数据段基地址                                                       |

### header\_item

appears in the header section alignment: 4 bytes

| Name              | Format                       | Description                                                                                                                                                                                                                                                                                                                     |
| ----------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| magic             | ubyte\[8] = DEX\_FILE\_MAGIC | magic value. See discussion above under "DEX\_FILE\_MAGIC" for more details.                                                                                                                                                                                                                                                    |
| checksum          | uint                         | adler32 checksum of the rest of the file (everything but magic and this field); used to detect file corruption                                                                                                                                                                                                                  |
| signature         | ubyte\[20]                   | SHA-1 signature (hash) of the rest of the file (everything but magic, checksum, and this field); used to uniquely identify files                                                                                                                                                                                                |
| file\_size        | uint                         | size of the entire file (including the header), in bytes                                                                                                                                                                                                                                                                        |
| header\_size      | uint = 0x70                  | size of the header (this entire section), in bytes. This allows for at least a limited amount of backwards/forwards compatibility without invalidating the format.                                                                                                                                                              |
| endian\_tag       | uint = ENDIAN\_CONSTANT      | endianness tag. See discussion above under "ENDIAN\_CONSTANT and REVERSE\_ENDIAN\_CONSTANT" for more details.                                                                                                                                                                                                                   |
| link\_size        | uint                         | size of the link section, or 0 if this file isn't statically linked                                                                                                                                                                                                                                                             |
| link\_off         | uint                         | offset from the start of the file to the link section, or 0 if link\_size == 0. The offset, if non-zero, should be to an offset into the link\_data section. The format of the data pointed at is left unspecified by this document; this header field (and the previous) are left as hooks for use by runtime implementations. |
| map\_off          | uint                         | offset from the start of the file to the map item. The offset, which must be non-zero, should be to an offset into the data section, and the data should be in the format specified by "map\_list" below.                                                                                                                       |
| string\_ids\_size | uint                         | count of strings in the string identifiers list                                                                                                                                                                                                                                                                                 |
| string\_ids\_off  | uint                         | offset from the start of the file to the string identifiers list, or 0 if string\_ids\_size == 0 (admittedly a strange edge case). The offset, if non-zero, should be to the start of the string\_ids section.                                                                                                                  |
| type\_ids\_size   | uint                         | count of elements in the type identifiers list, at most 65535                                                                                                                                                                                                                                                                   |
| type\_ids\_off    | uint                         | offset from the start of the file to the type identifiers list, or 0 if type\_ids\_size == 0 (admittedly a strange edge case). The offset, if non-zero, should be to the start of the type\_ids section.                                                                                                                        |
| proto\_ids\_size  | uint                         | count of elements in the prototype identifiers list, at most 65535                                                                                                                                                                                                                                                              |
| proto\_ids\_off   | uint                         | offset from the start of the file to the prototype identifiers list, or 0 if proto\_ids\_size == 0 (admittedly a strange edge case). The offset, if non-zero, should be to the start of the proto\_ids section.                                                                                                                 |
| field\_ids\_size  | uint                         | count of elements in the field identifiers list                                                                                                                                                                                                                                                                                 |
| field\_ids\_off   | uint                         | offset from the start of the file to the field identifiers list, or 0 if field\_ids\_size == 0. The offset, if non-zero, should be to the start of the field\_ids section.                                                                                                                                                      |
| method\_ids\_size | uint                         | count of elements in the method identifiers list                                                                                                                                                                                                                                                                                |
| method\_ids\_off  | uint                         | offset from the start of the file to the method identifiers list, or 0 if method\_ids\_size == 0. The offset, if non-zero, should be to the start of the method\_ids section.                                                                                                                                                   |
| class\_defs\_size | uint                         | count of elements in the class definitions list                                                                                                                                                                                                                                                                                 |
| class\_defs\_off  | uint                         | offset from the start of the file to the class definitions list, or 0 if class\_defs\_size == 0 (admittedly a strange edge case). The offset, if non-zero, should be to the start of the class\_defs section.                                                                                                                   |
| data\_size        | uint                         | Size of data section in bytes. Must be an even multiple of sizeof(uint).                                                                                                                                                                                                                                                        |
| data\_off         | uint                         | offset from the start of the file to the start of the data section.                                                                                                                                                                                                                                                             |

### magic value

> 魔法字段

前4个字节为格式，`dex\n`:dex文件格式； `dey\n`:优化的dex文件。

后4个字节为文件格式的版本号> `035\0`:dex支持版本号； `036\0`:dey支持版本号；

### checksum value

> 检验码字段

主要用来检查从这个字段开始到文件结尾，这段数据是否完整，有没有人修改过，或者传送过程中是否有出错等等。

通常用来检查数据是否完整的算法，有 CRC32、有SHA128等， 但这里采用并不是这两类，而采用一个比较特别的算法，叫做**adler32**，这是在开源zlib里常用的算法，用来检查文件是否完整性。该算法由MarkAdler发明，其可靠程度跟CRC32差不多，不过还是弱一点点，但它有一个很好的优点，就是使用软件来计算检验码时比较 CRC32要快很多。可见Android系统，就算法上就已经为移动设备进行优化了。

`Java中可使用java.util.zip.Adler32类做校验操作` <https://developer.android.com/reference/java/util/zip/Adler32.html>

`A class that can be used to compute the Adler-32 checksum of a data stream. An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster.`

### signature value

> 签名字段(SHA-1)

验证文件是否完整，这样确保执行的文件完整和安全

### file\_size

本文件的大小，通过endian\_tag=0x78563412,看出，此值是通过小端编码来存储此值的。一般系统的Block大小为`4096 Bytes`。 eg：`ox28441600`，表示值为`0x00164428`bytes=`1459240`bytes=`1425.039...`K=`1.3916...`M 此文件在Mac下使用`du`查看时

```
$ du -msh classes.dex
1.4M
$ du classes.dex
2856
```

### map\_off value

这个字段主要保存map开始位置，就是从文件头开始到map数据的长度，通过这个索引就可以找到map数据。map的数据结构如下：

| 名称   | 大小  | 说明                       |
| ---- | --- | ------------------------ |
| size | 4字节 | map里项的个数                 |
| list | 变长  | 每一项定义为12字节，项的个数由上面项大小决定。 |
