This page follows the Android Open Source Project’s Dalvik executable format specification: the data types, the versions, the header, the order of the sections and the map list that indexes them. The tables those sections hold are on the ID tables page.
Data types
All multi-byte numbers are little-endian.
| Name | Size | Meaning |
|---|---|---|
byte | 1 | Signed 8-bit integer. |
ubyte | 1 | Unsigned 8-bit integer. |
short | 2 | Signed 16-bit integer. |
ushort | 2 | Unsigned 16-bit integer. |
int | 4 | Signed 32-bit integer. |
uint | 4 | Unsigned 32-bit integer. |
long | 8 | Signed 64-bit integer. |
ulong | 8 | Unsigned 64-bit integer. |
sleb128 | 1–5 | Signed LEB128. |
uleb128 | 1–5 | Unsigned LEB128. |
uleb128p1 | 1–5 | The value plus one, as a uleb128, so that −1 (NO_INDEX) takes one byte. |
LEB128
Each byte holds seven bits of the value, lowest first; its top bit is 1 if another byte
follows. DEX allows at most five bytes, enough for a 32-bit value. For
sleb128 the top bit of the last byte’s seven is the sign and is extended.
| Bytes | sleb128 | uleb128 | uleb128p1 |
|---|---|---|---|
00 | 0 | 0 | −1 |
01 | 1 | 1 | 0 |
7F | −1 | 127 | 126 |
80 7F | −128 | 16,256 | 16,255 |
Constants
| Name | Value | Meaning |
|---|---|---|
DEX_FILE_MAGIC | 64 65 78 0A v v v 00 | dex\n, three ASCII digits of version, a zero byte. The newline and zero catch some kinds of corruption. |
ENDIAN_CONSTANT | 0x12345678 | The endian_tag of a normal, little-endian file. |
REVERSE_ENDIAN_CONSTANT | 0x78563412 | The endian_tag read from a byte-swapped file. |
NO_INDEX | 0xFFFFFFFF | No index (0 is a valid index). In uleb128p1 fields it is the byte 00. |
Versions
| Magic | Android | What it added |
|---|---|---|
dex\n009\0, dex\n013\0 | M3 and M5 pre-release builds | Early formats that differ a lot from the current one; not described by the specification. |
dex\n035\0 | up to 6.x | The long-standing format. |
dex\n037\0 | 7.0 | Default methods in interfaces, and changes to invoke rules for them. |
dex\n038\0 | 8.0 | invoke-polymorphic and invoke-custom, with the call-site and method-handle tables. |
dex\n039\0 | 9.0 | const-method-handle and const-method-type. Android 10 added hidden-API data to boot class path files. |
dex\n040\0 | 10 | More characters, including spaces, allowed in simple names. |
dex\n041\0 | 16 (experimental) | The container format. The specification says it is not for production use. |
Header
The header is 112 bytes (0x70) up to version 040 and 120 bytes
(0x78) from 041.
| Offset | Size | Type and name | Meaning |
|---|---|---|---|
0x00 | 8 | ubyte[8] magic | DEX_FILE_MAGIC with the version. |
0x08 | 4 | uint checksum | Adler-32 of the file from offset 12 to the end (everything except the magic and this field). |
0x0C | 20 | ubyte[20] signature | SHA-1 of the file from offset 32 to the end (everything except magic, checksum and this field). |
0x20 | 4 | uint file_size | Size of the whole file; from 041, of this logical file in the container. |
0x24 | 4 | uint header_size | 0x70, or 0x78 from 041. Lets the format grow. |
0x28 | 4 | uint endian_tag | ENDIAN_CONSTANT. |
0x2C | 4 | uint link_size | Size of the link section, 0 if the file is not statically linked. |
0x30 | 4 | uint link_off | Offset of the link section, or 0 when link_size is 0. |
0x34 | 4 | uint map_off | Offset of the map list in the data section. Never 0. |
0x38 | 4 | uint string_ids_size | Number of strings. |
0x3C | 4 | uint string_ids_off | Offset of string_ids, or 0 if there are none. |
0x40 | 4 | uint type_ids_size | Number of types; at most 65,535. |
0x44 | 4 | uint type_ids_off | Offset of type_ids, or 0. |
0x48 | 4 | uint proto_ids_size | Number of prototypes; at most 65,535. |
0x4C | 4 | uint proto_ids_off | Offset of proto_ids, or 0. |
0x50 | 4 | uint field_ids_size | Number of field references. |
0x54 | 4 | uint field_ids_off | Offset of field_ids, or 0. |
0x58 | 4 | uint method_ids_size | Number of method references. |
0x5C | 4 | uint method_ids_off | Offset of method_ids, or 0. |
0x60 | 4 | uint class_defs_size | Number of class definitions. |
0x64 | 4 | uint class_defs_off | Offset of class_defs, or 0. |
0x68 | 4 | uint data_size | Size of the data section, an even multiple of sizeof(uint). Unused from 041. |
0x6C | 4 | uint data_off | Offset of the data section. Unused from 041. |
0x70 | 4 | uint container_size | 041 and later: size of the whole container file. Earlier files are taken to have it equal to file_size. |
0x74 | 4 | uint header_offset | 041 and later: offset of this header from the start of the container. Earlier files are taken to have 0. |
The method and field tables use 32-bit counts, but instructions refer to methods,
fields and types with 16-bit indexes (meth@BBBB and the like in the
instruction formats), so one
file can address at most 65,536 of each.
Sections
After the header the sections come in this order:
| Section | Item | Order and rules |
|---|---|---|
header | header_item | At offset 0. |
string_ids | string_id_item[] | Sorted by string contents in UTF-16 code-point order; no duplicates. |
type_ids | type_id_item[] | Sorted by string_id index; no duplicates. |
proto_ids | proto_id_item[] | Sorted by return type, then by argument list; no duplicates. |
field_ids | field_id_item[] | Sorted by defining type, then name, then type; no duplicates. |
method_ids | method_id_item[] | Sorted by defining type, then name, then prototype; no duplicates. |
class_defs | class_def_item[] | A class’s superclass and interfaces must appear before it. A class name appears at most once. |
call_site_ids | call_site_id_item[] | Sorted by call_site_off. |
method_handles | method_handle_item[] | Not sorted; may contain duplicates. |
data | various | Everything the tables point to. Items have their own alignment, with padding bytes before them as needed. |
link_data | — | Data for statically linked files. Its format is not specified; empty in unlinked files. |
Offsets in the file are from the start of the file (from 041, from the start of the container).
Map list
The map list, at map_off and aligned to 4 bytes, lists every section of the
file. Its entries are in offset order and must not overlap. Some items are only
reachable through the map, so a reader that wants every item should use it.
| Offset | Size | Type and name | Meaning |
|---|---|---|---|
0 | 4 | uint size | Number of entries. |
4 | 12 × size | map_item list[] | The entries. |
map_item
| Offset | Size | Type and name | Meaning |
|---|---|---|---|
0 | 2 | ushort type | Item type, from the table below. |
2 | 2 | ushort unused | — |
4 | 4 | uint size | Number of items at the offset. |
8 | 4 | uint offset | Offset of the first item. |
Type codes
| Code | Name | Item size | Alignment |
|---|---|---|---|
0x0000 | TYPE_HEADER_ITEM | 0x70 | 4 |
0x0001 | TYPE_STRING_ID_ITEM | 0x04 | 4 |
0x0002 | TYPE_TYPE_ID_ITEM | 0x04 | 4 |
0x0003 | TYPE_PROTO_ID_ITEM | 0x0C | 4 |
0x0004 | TYPE_FIELD_ID_ITEM | 0x08 | 4 |
0x0005 | TYPE_METHOD_ID_ITEM | 0x08 | 4 |
0x0006 | TYPE_CLASS_DEF_ITEM | 0x20 | 4 |
0x0007 | TYPE_CALL_SITE_ID_ITEM | 0x04 | 4 |
0x0008 | TYPE_METHOD_HANDLE_ITEM | 0x08 | 4 |
0x1000 | TYPE_MAP_LIST | 4 + 12 × size | 4 |
0x1001 | TYPE_TYPE_LIST | 4 + 2 × size | 4 |
0x1002 | TYPE_ANNOTATION_SET_REF_LIST | 4 + 4 × size | 4 |
0x1003 | TYPE_ANNOTATION_SET_ITEM | 4 + 4 × size | 4 |
0x2000 | TYPE_CLASS_DATA_ITEM | implicit | none |
0x2001 | TYPE_CODE_ITEM | implicit | 4 |
0x2002 | TYPE_STRING_DATA_ITEM | implicit | none |
0x2003 | TYPE_DEBUG_INFO_ITEM | implicit | none |
0x2004 | TYPE_ANNOTATION_ITEM | implicit | none |
0x2005 | TYPE_ENCODED_ARRAY_ITEM | implicit | none |
0x2006 | TYPE_ANNOTATIONS_DIRECTORY_ITEM | implicit | 4 |
0xF000 | TYPE_HIDDENAPI_CLASS_DATA_ITEM | implicit | not stated |
“Implicit” sizes have to be found by parsing the item.
Version 041 container
Version 041 lets several logical DEX files share one physical file, mostly by putting them one after another, so that they can share strings and other data:
file_sizeis the size of one logical file, so a reader can step from one header to the next.- A logical file may refer to data that lies later in the container, outside its own range.
- Every offset is from the start of the physical file, not from the header.
- The header gains
container_sizeandheader_offset, so it is0x78bytes. data_sizeanddata_offare not used, and the data of a logical file need not be in one piece.
Example
The first bytes of a version 035 file:
64 65 78 0A 30 33 35 00 magic "dex\n035\0"
xx xx xx xx checksum (Adler-32)
xx × 20 signature (SHA-1)
… at 0x24: 70 00 00 00 header_size 0x70
at 0x28: 78 56 34 12 endian_tag 0x12345678
Sources
The Android Open Source Project’s Dalvik executable format: “Simple data type definitions”, “LEB128”, “Embedded in header_item” (magic and versions), “endian_constant”, “NO_INDEX”, “File layout”, “header_item”, “map_list”, “map_item”, “Type codes”, the alignment given with each item, and the “Container format” notes for version 041. The 16-bit index limit is from the instruction formats.