В этом документе описывается структура и содержимое файлов .dex
, которые используются для хранения набора определений классов и связанных с ними дополнительных данных.
Руководство по типам
Имя | Описание |
---|---|
байт | 8-битное знаковое целое число |
юбайт | 8-битное беззнаковое целое число |
короткий | 16-битное знаковое целое число, с прямым порядком байтов |
ушорт | 16-битное беззнаковое целое число, с прямым порядком байтов |
инт | 32-битное знаковое целое число, с прямым порядком байтов |
единица измерения | 32-битное беззнаковое целое число, с прямым порядком байтов |
длинный | 64-битное знаковое целое число, с прямым порядком байтов |
улун | 64-битное беззнаковое целое число, с прямым порядком байтов |
слеб128 | подписанный LEB128, переменной длины (см. ниже) |
uleb128 | беззнаковый LEB128, переменной длины (см. ниже) |
uleb128p1 | беззнаковый LEB128 плюс 1 , переменной длины (см. ниже) |
ЛЕБ128
LEB128 (« Little -Endian Base 128 ») — это код переменной длины для произвольных знаковых и беззнаковых целых чисел. Формат был заимствован из спецификации DWARF3 . В .dex
файле LEB128 используется только для кодирования 32-битных чисел.
Каждое закодированное значение LEB128 состоит из одного-пяти байтов, которые вместе представляют одно 32-битное значение. У каждого байта установлен старший бит, за исключением последнего байта в последовательности, у которого старший бит сброшен. Остальные семь бит каждого байта составляют полезную нагрузку: младшие семь битов количества находятся в первом байте, следующие семь — во втором байте и так далее. В случае знакового LEB128 ( sleb128
) старший бит полезной нагрузки последнего байта в последовательности дополняется знаком для получения конечного значения. В случае беззнакового значения ( uleb128
) любые биты, не представленные явно, интерпретируются как 0
.
Побитовая диаграмма двухбайтового значения LEB128 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Первый байт | Второй байт | ||||||||||||||
1 | бит 6 | бит 5 | бит 4 | бит 3 | бит 2 | бит 1 | бит 0 | 0 | бит 13 | бит 12 | бит 11 | бит 10 | бит 9 | бит 8 | бит 7 |
Вариант uleb128p1
используется для представления знакового значения, где представление представляет собой значение плюс один, закодированное как uleb128
. Это позволяет кодировать -1
(альтернативно рассматриваемое как беззнаковое значение 0xffffffff
) — но не любое другое отрицательное число — одним байтом и полезно именно в тех случаях, когда представляемое число должно быть либо неотрицательным, либо -1
(или 0xffffffff
), и когда не допускаются другие отрицательные значения (или когда большие беззнаковые значения вряд ли понадобятся).
Вот несколько примеров форматов:
Закодированная последовательность | Как sleb128 | Как uleb128 | Как uleb128p1 |
---|---|---|---|
00 | 0 | 0 | -1 |
01 | 1 | 1 | 0 |
7ф | -1 | 127 | 126 |
80 7ф | -128 | 16256 | 16255 |
Расположение файла
Имя | Формат | Описание |
---|---|---|
заголовок | заголовок_элемент | заголовок |
string_ids | string_id_item[] | Список идентификаторов строк. Это идентификаторы всех строк, используемых в этом файле, как для внутреннего именования (например, дескрипторов типов), так и в качестве константных объектов, на которые ссылается код. Этот список должен быть отсортирован по содержимому строк с использованием кодовых точек UTF-16 (без учёта локали) и не должен содержать повторяющихся записей. |
type_ids | type_id_item[] | Список идентификаторов типов. Это идентификаторы всех типов (классов, массивов или примитивных типов), на которые ссылается этот файл, независимо от того, определены ли они в нём. Этот список должен быть отсортирован по индексу string_id и не должен содержать повторяющихся записей. |
proto_ids | proto_id_item[] | Список идентификаторов прототипов методов. Это идентификаторы всех прототипов, на которые ссылается этот файл. Этот список должен быть отсортирован по типу возвращаемого значения (по индексу type_id ), а затем по списку аргументов (лексикографический порядок, отдельные аргументы упорядочены по индексу type_id ). Список не должен содержать повторяющихся записей. |
field_ids | field_id_item[] | Список идентификаторов полей. Это идентификаторы всех полей, на которые ссылается этот файл, независимо от того, определены они в нём или нет. Этот список должен быть отсортирован, где тип определения (по индексу type_id ) — основной порядок, имя поля (по индексу string_id ) — промежуточный порядок, а тип (по индексу type_id ) — второстепенный порядок. Список не должен содержать повторяющихся записей. |
идентификаторы_методов | method_id_item[] | Список идентификаторов методов. Это идентификаторы всех методов, на которые ссылается этот файл, независимо от того, определены они в нём или нет. Этот список должен быть отсортирован, где тип определения (по индексу type_id ) — основной порядок, имя метода (по индексу string_id ) — промежуточный порядок, а прототип метода (по индексу proto_id ) — дополнительный порядок. Список не должен содержать повторяющихся записей. |
class_defs | class_def_item[] | Список определений классов. Классы должны быть упорядочены таким образом, чтобы суперкласс и реализованные интерфейсы данного класса появлялись в списке раньше ссылающегося на него класса. Более того, определение класса с тем же именем не может встречаться в списке более одного раза. |
call_site_ids | call_site_id_item[] | Список идентификаторов точек вызова. Это идентификаторы всех точек вызова, на которые ссылается этот файл, независимо от того, определены ли они в файле или нет. Этот список должен быть отсортирован по возрастанию значения call_site_off . |
method_handles | method_handle_item[] | Список дескрипторов методов. Список всех дескрипторов методов, на которые ссылается этот файл, независимо от того, определены они в файле или нет. Этот список не сортируется и может содержать дубликаты, которые логически соответствуют различным экземплярам дескрипторов методов. |
данные | ubyte[] | Область данных, содержащая все вспомогательные данные для перечисленных выше таблиц. Разные элементы имеют разные требования к выравниванию, и при необходимости перед каждым элементом добавляются байты заполнения для достижения правильного выравнивания. |
link_data | ubyte[] | Данные, используемые в статически скомпонованных файлах. Формат данных в этом разделе не определён в настоящем документе. В несвязанных файлах этот раздел пуст, и реализации среды выполнения могут использовать его по своему усмотрению. |
Формат контейнера
В версии 41 представлен новый формат контейнера для данных DEX, предназначенный для экономии места. Этот формат позволяет объединить несколько логических файлов DEX в один физический файл. Новый формат представляет собой, по сути, простое объединение файлов предыдущего формата с некоторыми отличиями:
-
file_size
— это размер логического, а не физического файла. Его можно использовать для перебора всех логических файлов в контейнере. - Логические dex-файлы могут ссылаться на любые более поздние данные в контейнере (но не более ранние). Это позволяет dex-файлам обмениваться данными, например строками, между собой.
- Все смещения указаны относительно физического файла. Смещение не указано относительно заголовка. Это гарантирует, что разделы со смещениями могут быть использованы совместно между логическими файлами.
- Заголовок добавляет два новых поля для описания границ контейнера. Это обеспечивает дополнительную проверку согласованности и упрощает портирование кода в новый формат.
-
data_size
иdata_off
теперь не используются. Данные могут быть распределены по нескольким логическим файлам и не обязательно должны быть смежными.
Определения битовых полей, строк и констант
DEX_FILE_MAGIC
Встроено в header_item
Константа массива/строки DEX_FILE_MAGIC
представляет собой список байтов, которые должны присутствовать в начале .dex
файла, чтобы он был распознан как таковой. Значение намеренно содержит символ новой строки ( "\n"
или 0x0a
) и нулевой байт ( "\0"
или 0x00
) для облегчения обнаружения определённых видов повреждений. Значение также кодирует номер версии формата в виде трёх десятичных цифр, который, как ожидается, будет монотонно увеличиваться по мере развития формата.
ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 } = "dex\n039\0"
Примечание: поддержка версии 041
формата была добавлена в выпуске Android 16, поддерживающем формат контейнера .
Примечание: Поддержка версии 040
формата была добавлена в выпуске Android 10.0, что расширило набор разрешенных символов в SimpleNames .
Примечание: Поддержка версии 039
формата была добавлена в выпуске Android 9.0, где были представлены два новых байт-кода: const-method-handle
и const-method-type
. (Каждый из них описан в таблице « Сводка набора байт-кодов» .) В Android 10 версия 039
расширяет формат файла DEX, включая скрытую информацию API, которая применима только к файлам DEX в пути к классу загрузки.
Примечание: Поддержка версии 038
формата была добавлена в версии Android 8.0. В версии 038
добавлены новые байт-коды ( invoke-polymorphic
и invoke-custom
) и данные для дескрипторов методов.
Примечание: Поддержка версии 037
формата была добавлена в версии Android 7.0. До версии 037
большинство версий Android использовали версию 035
формата. Единственное отличие между версиями 035
и 037
заключается в добавлении методов по умолчанию и изменении invoke
.
Примечание: как минимум несколько более ранних версий этого формата использовались в общедоступных релизах программного обеспечения. Например, версия 009
использовалась для релизов M3 платформы Android (ноябрь–декабрь 2007 г.), а версия 013
— для релизов M5 платформы Android (февраль–март 2008 г.). В ряде аспектов эти более ранние версии формата существенно отличаются от версии, описанной в данном документе.
ENDIAN_CONSTANT и REVERSE_ENDIAN_CONSTANT
Встроено в header_item
Константа ENDIAN_CONSTANT
используется для указания порядка байтов файла, в котором она находится. Хотя стандартный формат .dex
— little-endian, реализации могут выполнять перестановку байтов. Если реализация обнаружит заголовок, у которого endian_tag
равен REVERSE_ENDIAN_CONSTANT
вместо ENDIAN_CONSTANT
, она будет знать, что файл был переставлен байтами с ожидаемого формата.
uint ENDIAN_CONSTANT = 0x12345678; uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
НЕТ_ИНДЕКСА
Встроено в class_def_item и debug_info_item
Константа NO_INDEX
используется для указания отсутствия значения индекса.
Примечание: это значение не определено как 0
, поскольку на самом деле это обычно допустимый индекс.
Выбранное значение для NO_INDEX
можно представить как один байт в кодировке uleb128p1
.
uint NO_INDEX = 0xffffffff; // == -1 if treated as a signed int
определения access_flags
Встроено в class_def_item, encoded_field, encoded_method и InnerClass
Битовые поля этих флагов используются для указания доступности и общих свойств классов и членов класса.
Имя | Ценить | Для классов (и аннотаций InnerClass ) | Для полей | Для методов |
---|---|---|---|---|
ACC_PUBLIC | 0x1 | public : виден везде | public : виден везде | public : виден везде |
ACC_PRIVATE | 0x2 | private : виден только определяющему классу | private : виден только определяющему классу | private : виден только определяющему классу |
ACC_PROTECTED | 0x4 | protected : видно пакету и подклассам | protected : видно пакету и подклассам | protected : видно пакету и подклассам |
ACC_STATIC | 0x8 | static : не создается с внешней ссылкой this | static : глобальный для определения класса | static : не принимает this аргумент |
ACC_FINAL | 0x10 | final : не подклассифицируется | final : неизменяемый после построения | final : не подлежит переопределению |
ACC_SYNCHRONIZED | 0x20 | synchronized : соответствующая блокировка автоматически устанавливается при вызове этого метода. Примечание: этот параметр можно задать только в том случае, если также установлен | ||
ACC_VOLATILE | 0x40 | volatile : специальные правила доступа, обеспечивающие безопасность потоков | ||
ACC_BRIDGE | 0x40 | метод моста, автоматически добавляемый компилятором как типобезопасный мост | ||
ACC_TRANSIENT | 0x80 | transient : не сохраняется при сериализации по умолчанию | ||
ACC_VARARGS | 0x80 | последний аргумент должен рассматриваться компилятором как «остальной» аргумент | ||
ACC_NATIVE | 0x100 | native : реализован в машинном коде | ||
ACC_INTERFACE | 0x200 | interface : многократно реализуемый абстрактный класс | ||
ACC_ABSTRACT | 0x400 | abstract : не допускающий непосредственного создания экземпляров | abstract : не реализовано этим классом | |
ACC_STRICT | 0x800 | strictfp : строгие правила для арифметики с плавающей точкой | ||
ACC_SYNTHETIC | 0x1000 | не определено напрямую в исходном коде | не определено напрямую в исходном коде | не определено напрямую в исходном коде |
ACC_ANNOTATION | 0x2000 | объявлен как класс аннотации | ||
ACC_ENUM | 0x4000 | объявлен как перечисляемый тип | объявлено как перечисляемое значение | |
(неиспользованный) | 0x8000 | |||
ACC_CONSTRUCTOR | 0x10000 | метод конструктора (инициализатор класса или экземпляра) | ||
ACC_DECLARED_ СИНХРОНИЗИРОВАННЫЙ | 0x20000 | объявлен synchronized .Примечание: это не оказывает никакого влияния на выполнение (за исключением отражения этого флага как такового). |
InnerClass
и никогда не должно быть включено в class_def_item
.
Измененная кодировка UTF-8
В качестве уступки для упрощения поддержки устаревших форматов формат .dex
кодирует строковые данные в фактически стандартной модифицированной форме UTF-8, далее именуемой MUTF-8. Эта форма идентична стандартной UTF-8, за исключением:
- Используются только одно-, двух- и трехбайтовые кодировки.
- Кодовые точки в диапазоне
U+10000
…U+10ffff
кодируются как суррогатная пара, каждая из которых представлена трехбайтовым кодированным значением. - Кодовая точка
U+0000
кодируется в двухбайтовой форме. - Обычный нулевой байт (значение
0
) обозначает конец строки, что соответствует стандартной интерпретации языка C.
Первые два пункта выше можно обобщить следующим образом: MUTF-8 — это формат кодирования для UTF-16, а не более прямой формат кодирования для символов Unicode.
Последние два пункта выше позволяют одновременно включать кодовую точку U+0000
в строку и по-прежнему обрабатывать ее как строку в стиле C с нулевым завершением.
Однако особая кодировка U+0000
означает, что, в отличие от обычного UTF-8, результат вызова стандартной функции C strcmp()
для пары строк MUTF-8 не всегда соответствует правильному знаку результата сравнения неравных строк. Когда важен порядок (а не только равенство), самый простой способ сравнения строк MUTF-8 — это декодировать их посимвольно и сравнить декодированные значения. (Однако возможны и более сложные реализации.)
Дополнительную информацию о кодировке символов см. в стандарте Unicode . MUTF-8 на самом деле ближе к (относительно менее известной) кодировке CESU-8, чем к самой UTF-8.
кодирование encoded_value
Встроено в annotation_element и encoded_array_item
Значение encoded_value
— это закодированный фрагмент (почти) произвольных иерархически структурированных данных. Кодировка должна быть компактной и простой для анализа.
Имя | Формат | Описание |
---|---|---|
(value_arg << 5) | value_type | юбайт | Байт, указывающий тип непосредственно следующего value , а также необязательный уточняющий аргумент в трёх старших битах. Различные определения value см. ниже. В большинстве случаев value_arg кодирует длину непосредственно следующего value в байтах, как (size - 1) , например, 0 означает, что значение занимает один байт, а 7 — восемь байт; однако существуют исключения, указанные ниже. |
ценить | ubyte[] | Байты, представляющие значение, имеют переменную длину и интерпретируются по-разному для разных байтов value_type , но всегда с прямым порядком байтов. Подробнее см. определения различных значений ниже. |
Форматы значений
Имя типа | value_type | Формат value_arg | Формат value | Описание |
---|---|---|---|---|
VALUE_BYTE | 0x00 | (нет; должно быть 0 ) | юбайт[1] | знаковое однобайтовое целое значение |
VALUE_SHORT | 0x02 | размер - 1 (0…1) | ubyte[размер] | знаковое двухбайтовое целое число, расширенное знаком |
VALUE_CHAR | 0x03 | размер - 1 (0…1) | ubyte[размер] | беззнаковое двухбайтовое целое значение, расширенное нулем |
VALUE_INT | 0x04 | размер - 1 (0…3) | ubyte[размер] | знаковое четырехбайтовое целое число, расширенное знаком |
VALUE_LONG | 0x06 | размер - 1 (0…7) | ubyte[размер] | знаковое восьмибайтовое целое число, расширенное знаком |
VALUE_FLOAT | 0x10 | размер - 1 (0…3) | ubyte[размер] | Четырехбайтовая битовая комбинация, расширенная нулем вправо и интерпретируемая как 32-битное значение с плавающей запятой IEEE754 |
VALUE_DOUBLE | 0x11 | размер - 1 (0…7) | ubyte[размер] | восьмибайтовый битовый шаблон, расширенный нулем вправо и интерпретируемый как 64-битное значение с плавающей запятой IEEE754 |
VALUE_METHOD_TYPE | 0x15 | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе proto_ids и представляющее значение типа метода |
VALUE_METHOD_HANDLE | 0x16 | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе method_handles и представляющее значение дескриптора метода |
VALUE_STRING | 0x17 | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе string_ids и представляющее строковое значение |
ЗНАЧЕНИЕ_ТИП | 0x18 | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе type_ids и представляющее собой рефлексивное значение типа/класса |
ЗНАЧЕНИЕ_ПОЛЯ | 0x19 | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе field_ids и представляющее собой отражающее значение поля |
VALUE_METHOD | 0x1a | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе method_ids и представляющее значение рефлексивного метода |
VALUE_ENUM | 0x1b | размер - 1 (0…3) | ubyte[размер] | беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе field_ids и представляющее значение константы перечисляемого типа |
ЗНАЧЕНИЕ_МАССИВ | 0x1c | (нет; должно быть 0 ) | закодированный_массив | Массив значений в формате, указанном ниже в параметре « encoded_array format». Размер value подразумевается при кодировании. |
ЗНАЧЕНИЕ_АННОТАЦИЯ | 0x1d | (нет; должно быть 0 ) | закодированная_аннотация | Вложенная аннотация в формате, указанном ниже в параметре « encoded_annotation format». Размер value подразумевается при кодировании. |
VALUE_NULL | 0x1e | (нет; должно быть 0 ) | (никто) | null справочное значение |
VALUE_BOOLEAN | 0x1f | логическое значение (0…1) | (никто) | Однобитное значение: 0 — false , 1 — true . Бит представлен в value_arg . |
формат encoded_array
Имя | Формат | Описание |
---|---|---|
размер | uleb128 | количество элементов в массиве |
ценности | закодированное_значение[размер] | серия последовательностей байтов size encoded_value в формате, указанном в этом разделе, соединенных последовательно. |
формат encoded_annotation
Имя | Формат | Описание |
---|---|---|
type_idx | uleb128 | Тип аннотации. Это должен быть тип класса (не массива или примитива). |
размер | uleb128 | количество сопоставлений имени и значения в этой аннотации |
элементы | annotation_element[размер] | Элементы аннотации, представленные непосредственно в строке (не как смещения). Элементы должны быть отсортированы по возрастанию индекса string_id . |
формат annotation_element
Имя | Формат | Описание |
---|---|---|
имя_idx | uleb128 | Имя элемента, представленное как индекс в разделе string_ids . Строка должна соответствовать синтаксису MemberName , определённому выше. |
ценить | закодированное_значение | значение элемента |
Синтаксис строки
В .dex
файле существует несколько типов элементов, которые в конечном итоге ссылаются на строку. Следующие определения в стиле BNF указывают допустимый синтаксис для этих строк.
SimpleName
SimpleName является основой синтаксиса имён других вещей. Формат .dex
допускает здесь значительную свободу (гораздо большую, чем большинство распространённых исходных языков). Вкратце, простое имя состоит из любого алфавитного символа или цифры из набора low-ASCII, нескольких определённых символов из набора low-ASCII и большинства кодовых точек, не входящих в набор ASCII, которые не являются управляющими, пробелами или специальными символами. Начиная с версии 040
формат дополнительно допускает символы пробела (категория Unicode Zs
). Обратите внимание, что суррогатные кодовые точки (в диапазоне U+d800
… U+dfff
) сами по себе не считаются допустимыми символами имён , но допустимы дополнительные символы Unicode (которые представлены последней альтернативой правила для SimpleNameChar ), и они должны быть представлены в файле как пары суррогатных кодовых точек в кодировке MUTF-8.
SimpleName → | ||
SimpleNameChar ( SimpleNameChar )* | ||
SimpleNameChar → | ||
'A' … 'Z' | ||
| | 'a' … 'z' | |
| | '0' … '9' | |
| | ' ' | начиная с версии DEX 040 |
| | '$' | |
| | '-' | |
| | '_' | |
| | U+00a0 | начиная с версии DEX 040 |
| | U+00a1 … U+1fff | |
| | U+2000 … U+200a | начиная с версии DEX 040 |
| | U+2010 … U+2027 | |
| | U+202f | начиная с версии DEX 040 |
| | U+2030 … U+d7ff | |
| | U+e000 … U+ffef | |
| | U+10000 … U+10ffff |
Имя участника
используется field_id_item и method_id_item
MemberName — это имя члена класса, членами которого являются поля, методы и внутренние классы.
Имя участника → | |
SimpleName | |
| | '<' SimpleName '>' |
FullClassName
FullClassName — это полностью определенное имя класса, включающее необязательный спецификатор пакета, за которым следует обязательное имя.
FullClassName → | |
OptionalPackagePrefix SimpleName | |
OptionalPackagePrefix → | |
( SimpleName '/' )* |
TypeDescriptor
Используется type_id_item
TypeDescriptor — это представление любого типа, включая примитивы, классы, массивы и void
. Ниже приведены значения различных версий.
TypeDescriptor → | |
'V' | |
| | FieldTypeDescriptor |
FieldTypeDescriptor → | |
NonArrayFieldTypeDescriptor | |
| | ( '[' * 1…255) NonArrayFieldTypeDescriptor |
NonArrayFieldTypeDescriptor → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' ПолноеИмяКласса ';' |
ShortyDescriptor
Используется proto_id_item
ShortyDescriptor — это краткое представление прототипа метода, включая возвращаемые значения и параметры, за исключением того, что не существует различий между различными ссылочными типами (класс или массив). Вместо этого все ссылочные типы представлены одним символом 'L'
.
ShortyDescriptor → | |
ShortyReturnType ( ShortyFieldType )* | |
ShortyReturnType → | |
'V' | |
| | ShortyFieldType |
ShortyFieldType → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' |
Семантика TypeDescriptor
В этом заключается значение каждого из вариантов TypeDescriptor .
Синтаксис | Значение |
---|---|
В | void ; действительно только для возвращаемых типов |
З | boolean |
Б | byte |
С | short |
С | char |
я | int |
Дж. | long |
Ф | float |
Д | double |
L полностью/квалифицированное/Имя ; | класс fully.qualified.Name |
[ дескриптор | массив descriptor , который можно рекурсивно использовать для массивов массивов, хотя недопустимо иметь более 255 измерений. |
Предметы и связанные с ними структуры
В этом разделе содержатся определения для каждого из элементов верхнего уровня, которые могут присутствовать в файле .dex
.
заголовок_элемент
Появляется в заголовочном разделе
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
магия | ubyte[8] = DEX_FILE_MAGIC | Магическое значение. Подробнее см. обсуждение выше в разделе « DEX_FILE_MAGIC ». |
контрольная сумма | единица измерения | adler32 контрольная сумма остальной части файла (все, кроме magic и этого поля); используется для обнаружения повреждения файла |
подпись | юбайт[20] | SHA-1-подпись (хэш) остальной части файла (все, кроме magic , checksum и этого поля); используется для уникальной идентификации файлов |
размер_файла | единица измерения | размер всего файла (включая заголовок) в байтах (v40 или более ранняя версия) расстояние в байтах от начала данного заголовка до следующего заголовка или до конца всего файла (контейнера). (v41 или более поздняя версия) |
размер_заголовка | единица измерения | Размер заголовка (всего этого раздела) в байтах. Это обеспечивает хотя бы ограниченную обратную и прямую совместимость без нарушения формата. должно быть 0x70 (112) байт (v40 или ниже) должен быть 0x78 (120) байт (v41 или более поздняя версия) |
endian_tag | uint = ENDIAN_CONSTANT | Тег порядка байтов. Подробнее см. выше в разделах « ENDIAN_CONSTANT и REVERSE_ENDIAN_CONSTANT ». |
размер_ссылки | единица измерения | размер раздела ссылки или 0 , если этот файл не связан статически |
ссылка_выкл | единица измерения | Смещение от начала файла до раздела link или 0 , если link_size == 0 Смещение, если оно не равно нулю, должно быть равно смещению в раздел link_data . Формат указываемых данных в данном документе не определён; это поле заголовка (и предыдущее) оставлено в качестве хуков для использования реализациями среды выполнения. |
map_off | единица измерения | Смещение от начала файла до элемента карты. Смещение должно быть ненулевым и должно соответствовать смещению в разделе data , а данные должны быть представлены в формате, указанном в параметре « map_list » ниже. |
string_ids_size | единица измерения | количество строк в списке идентификаторов строк |
string_ids_off | единица измерения | Смещение от начала файла до списка идентификаторов строк или 0 , если string_ids_size == 0 (хотя это, конечно, странный случай). Если смещение ненулевое, оно должно быть равно началу раздела string_ids . |
type_ids_size | единица измерения | количество элементов в списке идентификаторов типов, не более 65535 |
type_ids_off | единица измерения | Смещение от начала файла до списка идентификаторов типов или 0 , если type_ids_size == 0 (хотя это, конечно, странный случай). Если смещение ненулевое, оно должно быть указано до начала раздела type_ids . |
proto_ids_size | единица измерения | количество элементов в списке идентификаторов прототипов, не более 65535 |
proto_ids_off | единица измерения | Смещение от начала файла до списка идентификаторов прототипов или 0 , если proto_ids_size == 0 (хотя это, конечно, странный случай). Если смещение ненулевое, оно должно быть равно началу раздела proto_ids . |
field_ids_size | единица измерения | количество элементов в списке идентификаторов полей |
field_ids_off | единица измерения | Смещение от начала файла до списка идентификаторов полей или 0 , если field_ids_size == 0 Если смещение не равно нулю, оно должно быть указано до начала раздела field_ids . |
method_ids_size | единица измерения | количество элементов в списке идентификаторов методов |
method_ids_off | единица измерения | Смещение от начала файла до списка идентификаторов методов или 0 , если method_ids_size == 0 Если смещение не равно нулю, оно должно быть указано до начала раздела method_ids . |
class_defs_size | единица измерения | количество элементов в списке определений классов |
class_defs_off | единица измерения | Смещение от начала файла до списка определений классов или 0 , если class_defs_size == 0 (хотя это, конечно, странный случай). Если смещение ненулевое, оно должно быть указано до начала раздела class_defs . |
размер_данных | единица измерения | Размер раздела Неиспользованный (v41 или более поздняя версия) |
data_off | единица измерения | смещение от начала файла до начала раздела Неиспользованный (v41 или более поздняя версия) |
размер_контейнера | единица измерения | Это поле не существует. Можно предположить, что оно равно размер всего файла (включая другие заголовки dex и их данные). (v41 или более поздняя версия) |
смещение_заголовка | единица измерения | Это поле не существует. Можно предположить, что оно равно смещение от начала файла до начала этого заголовка. (v41 или более поздняя версия) |
список_карт
Появляется в разделе данных
Ссылка из header_item
Выравнивание: 4 байта
Это список всего содержимого файла, упорядоченный по порядку. Он содержит некоторую избыточность относительно header_item
, но предназначен для удобства использования в качестве итератора по всему файлу. Заданный тип должен встречаться в карте не более одного раза, но нет ограничений на порядок, в котором могут появляться типы, за исключением ограничений, накладываемых остальной частью формата (например, сначала должен идти раздел header
, затем раздел string_ids
и т. д.). Кроме того, записи карты должны быть упорядочены по начальному смещению и не должны перекрываться.
Имя | Формат | Описание |
---|---|---|
размер | единица измерения | размер списка, в записях |
список | map_item[размер] | элементы списка |
формат map_item
Имя | Формат | Описание |
---|---|---|
тип | ушорт | тип предметов; см. таблицу ниже |
неиспользованный | ушорт | (неиспользованный) |
размер | единица измерения | подсчет количества предметов, которые можно найти по указанному смещению |
компенсировать | единица измерения | смещение от начала файла до рассматриваемых элементов |
Тип кодов
Тип элемента | Постоянный | Ценить | Размер элемента в байтах |
---|---|---|---|
заголовок_элемент | TYPE_HEADER_ITEM | 0x0000 | 0x70 |
string_id_item | TYPE_STRING_ID_ITEM | 0x0001 | 0x04 |
type_id_item | TYPE_TYPE_ID_ITEM | 0x0002 | 0x04 |
proto_id_item | TYPE_PROTO_ID_ITEM | 0x0003 | 0x0c |
field_id_item | TYPE_FIELD_ID_ITEM | 0x0004 | 0x08 |
method_id_item | TYPE_METHOD_ID_ITEM | 0x0005 | 0x08 |
class_def_item | TYPE_CLASS_DEF_ITEM | 0x0006 | 0x20 |
call_site_id_item | TYPE_CALL_SITE_ID_ITEM | 0x0007 | 0x04 |
method_handle_item | TYPE_METHOD_HANDLE_ITEM | 0x0008 | 0x08 |
список_карт | TYPE_MAP_LIST | 0x1000 | 4 + (размер предмета * 12) |
type_list | TYPE_TYPE_LIST | 0x1001 | 4 + (размер предмета * 2) |
annotation_set_ref_list | TYPE_ANNOTATION_SET_REF_LIST | 0x1002 | 4 + (размер предмета * 4) |
annotation_set_item | TYPE_ANNOTATION_SET_ITEM | 0x1003 | 4 + (размер предмета * 4) |
class_data_item | TYPE_CLASS_DATA_ITEM | 0x2000 | неявный; необходимо разобрать |
код_элемента | TYPE_CODE_ITEM | 0x2001 | неявный; необходимо разобрать |
string_data_item | TYPE_STRING_DATA_ITEM | 0x2002 | неявный; необходимо разобрать |
debug_info_item | TYPE_DEBUG_INFO_ITEM | 0x2003 | неявный; необходимо разобрать |
annotation_item | TYPE_ANNOTATION_ITEM | 0x2004 | неявный; необходимо разобрать |
закодированный_элемент_массива | TYPE_ENCODED_ARRAY_ITEM | 0x2005 | неявный; необходимо разобрать |
annotations_directory_item | TYPE_ANNOTATIONS_DIRECTORY_ITEM | 0x2006 | неявный; необходимо разобрать |
hiddenapi_class_data_item | TYPE_HIDDENAPI_CLASS_DATA_ITEM | 0xF000 | неявный; необходимо разобрать |
string_id_item
Появляется в разделе string_ids
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
string_data_off | единица измерения | Смещение от начала файла до строковых данных этого элемента. Смещение должно быть указано до позиции в разделе data , а данные должны быть представлены в формате, указанном в параметре " string_data_item " ниже. Выравнивание смещения не требуется. |
string_data_item
Появляется в разделе данных
Выравнивание: отсутствует (выравнивание по байтам)
Имя | Формат | Описание |
---|---|---|
utf16_size | uleb128 | Размер этой строки в кодовых единицах UTF-16 (что во многих системах является «длиной строки»). То есть, это декодированная длина строки. (Закодированная длина определяется положением 0 байта.) |
данные | ubyte[] | последовательность кодовых единиц MUTF-8 (также известных как октеты, также известные как байты), за которыми следует байт со значением 0 Подробности и обсуждение формата данных см. в разделе «Кодировка MUTF-8 (модифицированная UTF-8)» выше. Примечание: допускается строка, включающая (в закодированной форме) суррогатные кодовые единицы UTF-16 (то есть |
type_id_item
Появляется в разделе type_ids
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
descriptor_idx | единица измерения | Индекс строки-дескриптора этого типа в списке string_ids . Строка должна соответствовать синтаксису TypeDescriptor , определённому выше. |
proto_id_item
Появляется в разделе proto_ids
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
shorty_idx | единица измерения | Индекс в списке string_ids для строки краткого дескриптора этого прототипа. Строка должна соответствовать синтаксису ShortyDescriptor , определенному выше, и должна соответствовать типу возвращаемого значения и параметрам этого элемента. |
return_type_idx | единица измерения | индекс в списке type_ids для возвращаемого типа этого прототипа |
параметры_выкл | единица измерения | Смещение от начала файла до списка типов параметров для данного прототипа или 0 , если у прототипа нет параметров. Если это смещение не равно нулю, оно должно находиться в разделе data , а данные должны быть представлены в формате, указанном в "type_list" ниже. Кроме того, в списке не должно быть ссылок на тип void . |
field_id_item
Появляется в разделе field_ids
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
class_idx | ушорт | Индекс в списке type_ids для определения этого поля. Это должен быть тип класса, а не массив или примитивный тип. |
type_idx | ушорт | индекс в списке type_ids для типа этого поля |
имя_idx | единица измерения | Добавьте индекс в список string_ids для имени этого поля. Строка должна соответствовать синтаксису MemberName , определённому выше. |
method_id_item
Появляется в разделе method_ids
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
class_idx | ушорт | Индекс в списке type_ids для определения этого метода. Это должен быть тип класса или массива, а не примитивный тип. |
proto_idx | ушорт | индекс в списке proto_ids для прототипа этого метода |
имя_idx | единица измерения | Добавьте индекс в список string_ids для имени этого метода. Строка должна соответствовать синтаксису MemberName , определённому выше. |
class_def_item
Появляется в разделе class_defs
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
class_idx | единица измерения | Индекс в списке type_ids для этого класса. Это должен быть тип класса, а не массив или примитивный тип. |
флаги_доступа | единица измерения | Флаги доступа для класса ( public , final и т. д.). Подробности см. в разделе «Определения access_flags ». |
superclass_idx | единица измерения | Индекс в списке type_ids для суперкласса или константа NO_INDEX , если у этого класса нет суперкласса (т. е. это корневой класс, такой как Object ). Если он присутствует, это должен быть тип класса, а не массив или примитивный тип. |
interfaces_off | единица измерения | Смещение от начала файла до списка интерфейсов или 0 , если интерфейсов нет. Это смещение должно находиться в разделе data , а данные должны быть представлены в формате, указанном ниже в параметре « type_list ». Каждый элемент списка должен быть типом класса (не массивом или примитивным типом), и не должно быть дубликатов. |
source_file_idx | единица измерения | Индекс в списке string_ids для имени файла, содержащего исходный код (по крайней мере, большей его части) этого класса, или специальное значение NO_INDEX для обозначения отсутствия этой информации. Элемент debug_info_item любого метода может переопределить этот исходный файл, но предполагается, что большинство классов будут получены только из одного исходного файла. |
аннотации_выкл | единица измерения | Смещение от начала файла до структуры аннотаций для данного класса или 0 , если аннотаций для данного класса нет. Если это смещение не равно нулю, оно должно находиться в разделе data , а данные должны быть представлены в формате, указанном ниже в параметре " annotations_directory_item ", при этом все элементы должны ссылаться на этот класс как на определитель. |
class_data_off | единица измерения | Смещение от начала файла до связанных данных класса для этого элемента или 0 , если для этого класса нет данных класса. (Это может быть, например, если этот класс является интерфейсом маркера.) Смещение, если оно не равно нулю, должно находиться в разделе data , а данные там должны иметь формат, указанный ниже параметром « class_data_item », при этом все элементы должны ссылаться на этот класс как на определитель. |
статические_значения_выкл | единица измерения | смещение от начала файла до списка начальных значений для static полей или 0 , если их нет (и все static поля должны быть инициализированы с помощью 0 или null ). Это смещение должно находиться в разделе data , а данные там должны быть в формате, указанном в « encoded_array_item » ниже. Размер массива не должен превышать количества static полей, объявленных этим классом, а элементы соответствуют static полям в том же порядке, как объявлено в соответствующем field_list . Тип каждого элемента массива должен соответствовать объявленному типу соответствующего поля. Если в массиве меньше элементов, чем static полей, то оставшиеся поля инициализируются соответствующим типом 0 или null . |
call_site_id_item
Появляется в разделе call_site_ids
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
call_site_off | единица измерения | смещение от начала файла для вызова определения сайта. Смещение должно находиться в разделе данных, а данные там должны быть в формате, указанном в параметре «call_site_item» ниже. |
call_site_item
Появляется в разделе данных
Выравнивание: нет (выровнено по байтам)
Call_site_item — это encoded_array_item, элементы которого соответствуют аргументам, предоставленным методу компоновщика начальной загрузки. Первые три аргумента:
- Дескриптор метода, представляющий метод компоновщика начальной загрузки (VALUE_METHOD_HANDLE).
- Имя метода, которое должен разрешить компоновщик начальной загрузки (VALUE_STRING).
- Тип метода, соответствующий типу имени метода, подлежащего разрешению (VALUE_METHOD_TYPE).
Любые дополнительные аргументы представляют собой постоянные значения, передаваемые методу компоновщика начальной загрузки. Эти аргументы передаются по порядку и без каких-либо преобразований типов.
Дескриптор метода, представляющий метод компоновщика начальной загрузки, должен иметь тип возвращаемого значения java.lang.invoke.CallSite
. Первые три типа параметров:
-
java.lang.invoke.Lookup
-
java.lang.String
-
java.lang.invoke.MethodType
Типы параметров любых дополнительных аргументов определяются по их постоянным значениям.
метод_handle_item
Появляется в разделе Method_handles.
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
метод_handle_type | сокращать | тип дескриптора метода; см. таблицу ниже |
неиспользованный | сокращать | (не используется) |
field_or_method_id | сокращать | Идентификатор поля или метода в зависимости от того, является ли тип дескриптора метода средством доступа или вызовом метода. |
неиспользованный | сокращать | (не используется) |
Коды типов дескрипторов методов
Постоянный | Ценить | Описание |
---|---|---|
METHOD_HANDLE_TYPE_STATIC_PUT | 0x00 | Дескриптор метода — это статический установщик поля (аксессор). |
METHOD_HANDLE_TYPE_STATIC_GET | 0x01 | Дескриптор метода — это метод получения статического поля (аксессор). |
METHOD_HANDLE_TYPE_INSTANCE_PUT | 0x02 | Дескриптор метода — это установщик поля экземпляра (аксессор). |
METHOD_HANDLE_TYPE_INSTANCE_GET | 0x03 | Дескриптор метода — это метод получения поля экземпляра (аксессор). |
METHOD_HANDLE_TYPE_INVOKE_STATIC | 0x04 | Дескриптор метода является вызовом статического метода. |
METHOD_HANDLE_TYPE_INVOKE_INSTANCE | 0x05 | Дескриптор метода является вызовом метода экземпляра. |
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR | 0x06 | Дескриптор метода является вызовом метода конструктора. |
METHOD_HANDLE_TYPE_INVOKE_DIRECT | 0x07 | Дескриптор метода является прямым вызовом метода. |
METHOD_HANDLE_TYPE_INVOKE_INTERFACE | 0x08 | Дескриптор метода — это вызов метода интерфейса. |
class_data_item
Ссылка из class_def_item
Появляется в разделе данных
Выравнивание: нет (выровнено по байтам)
Имя | Формат | Описание |
---|---|---|
static_fields_size | улеб128 | количество статических полей, определенных в этом элементе |
instance_fields_size | улеб128 | количество полей экземпляра, определенных в этом элементе |
Direct_methods_size | улеб128 | количество прямых методов, определенных в этом пункте |
virtual_methods_size | улеб128 | количество виртуальных методов, определенных в этом пункте |
static_fields | закодированное_поле[static_fields_size] | определенные статические поля, представленные как последовательность закодированных элементов. Поля должны быть отсортированы по field_idx в порядке возрастания. |
экземпляр_поля | закодированное_поле[размер_полей_экземпляра] | определенные поля экземпляра, представленные как последовательность закодированных элементов. Поля должны быть отсортированы по field_idx в порядке возрастания. |
прямые_методы | закодированный_метод[direct_methods_size] | определенные прямые (любые static , private или конструкторные) методы, представленные как последовательность закодированных элементов. Методы должны быть отсортированы по method_idx в порядке возрастания. |
виртуальные_методы | закодированный_метод[виртуальный_метод_размер] | определенные виртуальные (ни static , private , ни конструкторные) методы, представленные как последовательность закодированных элементов. Этот список не должен включать унаследованные методы, если они не переопределены классом, который представляет этот элемент. Методы должны быть отсортированы по method_idx в порядке возрастания. method_idx виртуального метода не должен совпадать с любым прямым методом. |
Примечание. Экземпляры field_id
и method_id
всех элементов должны ссылаться на один и тот же определяющий класс.
формат закодированного_поля
Имя | Формат | Описание |
---|---|---|
field_idx_diff | улеб128 | индекс в списке field_ids для идентификации этого поля (включает имя и дескриптор), представленный как отличие от индекса предыдущего элемента в списке. Индекс первого элемента в списке представляется напрямую. |
access_flags | улеб128 | флаги доступа к полю ( public , final и т. д.). Подробности см. в разделе «Определения access_flags ». |
формат закодированного_метода
Имя | Формат | Описание |
---|---|---|
метод_idx_diff | улеб128 | индекс в списке method_ids для идентификации этого метода (включая имя и дескриптор), представленный как отличие от индекса предыдущего элемента в списке. Индекс первого элемента в списке представляется напрямую. |
access_flags | улеб128 | флаги доступа для метода ( public , final и т. д.). Подробности см. в разделе «Определения access_flags ». |
code_off | улеб128 | смещение от начала файла до структуры кода для этого метода или 0 , если этот метод является abstract или native . Смещение должно быть в разделе data . Формат данных определяется параметром « code_item » ниже. |
список_типов
Ссылка на class_def_item и proto_id_item.
Появляется в разделе данных
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
размер | единица измерения | размер списка, в записях |
список | type_item[размер] | элементы списка |
формат type_item
Имя | Формат | Описание |
---|---|---|
type_idx | сокращать | индексировать в списке type_ids |
code_item
Ссылка из encoded_method
Появляется в разделе данных
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
регистры_размер | сокращать | количество регистров, используемых этим кодом |
ins_size | сокращать | количество слов входящих аргументов метода, для которого предназначен этот код |
outs_size | сокращать | количество слов исходящего пространства аргументов, необходимое этому коду для вызова метода |
пытается_размер | сокращать | количество try_item для этого экземпляра. Если они не равны нулю, то в этом экземпляре они отображаются как массив tries сразу после insns . |
debug_info_off | единица измерения | смещение от начала файла до последовательности отладочной информации (номера строк + информация о локальной переменной) для этого кода или 0 , если информации просто нет. Смещение, если оно не равно нулю, должно указывать на место в разделе data . Формат данных определяется параметром debug_info_item ниже. |
insns_size | единица измерения | размер списка инструкций, в 16-битных кодовых единицах |
гостиницы | ushort[insns_size] | фактический массив байт-кода. Формат кода в массиве insns определяется сопутствующим документом Dalvik bytecode . Обратите внимание: хотя он определяется как массив ushort , существуют некоторые внутренние структуры, которые предпочитают четырехбайтовое выравнивание. Кроме того, если это происходит в файле с обратным порядком байтов, то замена выполняется только для отдельных экземпляров ushort , а не для более крупных внутренних структур. |
прокладка | ushort (необязательно) = 0 | два байта заполнения для tries по четырем байтам. Этот элемент присутствует только в том случае, если tries_size не равно нулю, а insns_size нечетно. |
пытается | try_item[tries_size] (необязательно) | массив, указывающий, где в коде перехватываются исключения и как их обрабатывать. Элементы массива должны быть непересекающимися по диапазону и в порядке от младшего к старшему адресу. Этот элемент присутствует только в том случае, если tries_size не равно нулю. |
обработчики | encoded_catch_handler_list (необязательно) | байты, представляющие список списков типов перехвата и связанных с ним адресов обработчиков. Каждый try_item имеет побайтовое смещение в этой структуре. Этот элемент присутствует только в том случае, если tries_size не равно нулю. |
формат try_item
Имя | Формат | Описание |
---|---|---|
start_addr | единица измерения | начальный адрес блока кода, охватываемого этой записью. Адрес представляет собой количество 16-битных кодовых единиц до начала первой покрытой инструкции. |
insn_count | сокращать | количество 16-битных кодовых единиц, охватываемых этой записью. Последняя рассматриваемая единица кода (включительно) — start_addr + insn_count - 1 . |
handler_off | сокращать | смещение в байтах от начала связанного encoded_catch_hander_list до encoded_catch_handler для этой записи. Это должно быть смещение начала encoded_catch_handler . |
формат encoded_catch_handler_list
Имя | Формат | Описание |
---|---|---|
размер | улеб128 | размер этого списка, в записях |
список | encoded_catch_handler[handlers_size] | фактический список списков обработчиков, представленный напрямую (не как смещения) и последовательно объединенный |
формат encoded_catch_handler
Имя | Формат | Описание |
---|---|---|
размер | слеб128 | количество типов улова в этом списке. Если оно неположительное, то это отрицательное число типов перехвата, и за перехватами следует обработчик перехвата всех. Например: size 0 означает, что есть всеобъемлющий улов, но нет явно типизированных уловов. size 2 означает, что есть две явно типизированные ловушки и нет универсальной ловушки. А size -1 означает, что есть одна типизированная ловушка и всеобъемлющая. |
обработчики | encoded_type_addr_pair[abs(размер)] | поток элементов в кодировке abs(size) , по одному для каждого пойманного типа, в том порядке, в котором типы должны быть проверены. |
catch_all_addr | улеб128 (необязательно) | адрес байт-кода универсального обработчика. Этот элемент присутствует только в том случае, если size не является положительным. |
формат encoded_type_addr_pair
Имя | Формат | Описание |
---|---|---|
type_idx | улеб128 | индекс в списке type_ids для типа перехватываемого исключения |
адрес | улеб128 | адрес байт-кода соответствующего обработчика исключений |
debug_info_item
Ссылка из code_item
Появляется в разделе данных
Выравнивание: нет (выровнено по байтам)
Каждый debug_info_item
определяет конечный автомат с байтовым кодированием, основанный на DWARF3, который при интерпретации выдает таблицу позиций и (потенциально) информацию о локальной переменной для code_item
. Последовательность начинается с заголовка переменной длины (длина которого зависит от количества параметров метода), за ней следуют байт-коды конечного автомата и заканчивается байтом DBG_END_SEQUENCE
.
Государственный автомат состоит из пяти регистров. address
регистр представляет смещение инструкции в связанном insns_item
в 16-битных кодовых единицах. Регистр address
начинается с 0
в начале каждой последовательности debug_info
и должен только монотонно увеличиваться. Регистр line
определяет, какой номер исходной строки должен быть связан со следующей записью таблицы позиций, созданной конечным автоматом. Он инициализируется в заголовке последовательности и может изменяться в положительном или отрицательном направлении, но никогда не должен быть меньше 1
Регистр source_file
представляет исходный файл, на который ссылаются записи номера строки. Он инициализируется значением source_file_idx
в class_def_item
. Две другие переменные, prologue_end
и epilogue_begin
, представляют собой логические флаги (инициализированные значением false
), которые указывают, следует ли считать следующую выдаваемую позицию прологом или эпилогом метода. Конечный автомат также должен отслеживать имя и тип последней локальной переменной, действующей в каждом регистре кода DBG_RESTART_LOCAL
.
Заголовок следующий:
Имя | Формат | Описание |
---|---|---|
line_start | улеб128 | начальное значение для line регистра конечного автомата. Не представляет фактическую запись позиции. |
параметры_размер | улеб128 | количество закодированных имен параметров. Для каждого метода должен быть один параметр, исключая this метода экземпляра, если таковой имеется. |
имена_параметров | uleb128p1[размер_параметров] | строковый индекс имени параметра метода. Закодированное значение NO_INDEX указывает, что для связанного параметра нет имени. Дескриптор типа и подпись подразумеваются из дескриптора и подписи метода. |
Значения байт-кода следующие:
Имя | Ценить | Формат | Аргументы | Описание |
---|---|---|---|---|
DBG_END_SEQUENCE | 0x00 | (никто) | завершает последовательность отладочной информации для code_item | |
DBG_ADVANCE_PC | 0x01 | uleb128 addr_diff | addr_diff : сумма, добавляемая в адресный регистр. | перемещает регистр адреса без ввода записи о позиции |
DBG_ADVANCE_LINE | 0x02 | sleb128 line_diff | line_diff : сумма изменения регистра строки на | перемещает регистр строки без ввода записи позиции |
DBG_START_LOCAL | 0x03 | uleb128 регистр_номер uleb128p1 name_idx uleb128p1 type_idx | register_num : регистр, который будет содержать локальныйname_idx : строковый индекс имениtype_idx : индекс типа типа | вводит локальную переменную по текущему адресу. Либо name_idx , либо type_idx может быть NO_INDEX , чтобы указать, что это значение неизвестно. |
DBG_START_LOCAL_EXTENDED | 0x04 | uleb128 регистр_номер uleb128p1 name_idx uleb128p1 type_idx uleb128p1 sig_idx | register_num : регистр, который будет содержать локальныйname_idx : строковый индекс имениtype_idx : индекс типа типаsig_idx : строковый индекс сигнатуры типа | представляет локальный объект с сигнатурой типа по текущему адресу. Любое из name_idx , type_idx или sig_idx может быть NO_INDEX , чтобы указать, что это значение неизвестно. (Однако, если sig_idx равен -1 , те же данные можно было бы представить более эффективно, используя код операции DBG_START_LOCAL .) Примечание. Предостережения относительно обработки подписей см. в разделе « |
DBG_END_LOCAL | 0x05 | uleb128 регистр_номер | register_num : регистр, содержащий локальный | помечает действующую в данный момент локальную переменную как выходящую за пределы области действия по текущему адресу |
DBG_RESTART_LOCAL | 0x06 | uleb128 регистр_номер | register_num : зарегистрируйтесь для перезапуска | повторно вводит локальную переменную по текущему адресу. Имя и тип такие же, как у последнего локального компьютера, который находился в указанном реестре. |
DBG_SET_PROLOGUE_END | 0x07 | (никто) | устанавливает регистр конечного автомата prologue_end , указывая, что следующая добавляемая запись позиции должна считаться концом пролога метода (подходящее место для точки останова метода). Регистр prologue_end очищается любым специальным кодом операции ( >= 0x0a ). | |
DBG_SET_EPILOGUE_BEGIN | 0x08 | (никто) | устанавливает регистр конечного автомата epilogue_begin , указывая, что следующая добавленная запись позиции должна считаться началом эпилога метода (подходящее место для приостановки выполнения перед выходом из метода). Регистр epilogue_begin очищается любым специальным кодом операции ( >= 0x0a ). | |
DBG_SET_FILE | 0x09 | uleb128p1 name_idx | name_idx : строковый индекс имени исходного файла; NO_INDEX если неизвестно | указывает, что все последующие записи номеров строк ссылаются на это имя исходного файла, а не на имя по умолчанию, указанное в code_item |
Специальные коды операций | 0x0a…0xff | (никто) | перемещает регистры line и address , выдает запись позиции и очищает prologue_end и epilogue_begin . Описание смотрите ниже. |
Специальные коды операций
Коды операций со значениями от 0x0a
до 0xff
(включительно) перемещают как line
, так и address
регистры на небольшую величину, а затем создают новую запись в таблице позиций. Формула прибавки следующая:
DBG_FIRST_SPECIAL = 0x0a // the smallest special opcode DBG_LINE_BASE = -4 // the smallest line number increment DBG_LINE_RANGE = 15 // the number of line increments represented adjusted_opcode = opcode - DBG_FIRST_SPECIAL line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE) address += (adjusted_opcode / DBG_LINE_RANGE)
annotations_directory_item
Ссылка из class_def_item
Появляется в разделе данных
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
class_annotations_off | единица измерения | смещение от начала файла до аннотаций, сделанных непосредственно в классе, или 0 если класс не имеет прямых аннотаций. Смещение, если оно не равно нулю, должно указывать на место в разделе data . Формат данных определяется параметром « annotation_set_item » ниже. |
поля_размер | единица измерения | количество полей, аннотированных этим элементом |
annotated_methods_size | единица измерения | количество методов, аннотированных этим элементом |
annotated_parameters_size | единица измерения | количество списков параметров метода, аннотированных этим элементом |
field_annotations | field_annotation[fields_size] (необязательно) | список связанных аннотаций полей. Элементы списка должны быть отсортированы в порядке возрастания по field_idx . |
метод_аннотации | Method_annotation[methods_size] (необязательно) | список связанных аннотаций метода. Элементы списка должны быть отсортированы в порядке возрастания по method_idx . |
параметр_аннотации | параметр_аннотация[размер_параметров] (необязательно) | список связанных аннотаций параметров метода. Элементы списка должны быть отсортированы в порядке возрастания по method_idx . |
Примечание. Экземпляры field_id
и method_id
всех элементов должны ссылаться на один и тот же определяющий класс.
формат поля_аннотации
Имя | Формат | Описание |
---|---|---|
поле_idx | единица измерения | индекс в списке field_ids для идентификации аннотируемого поля |
аннотации_off | единица измерения | смещение от начала файла до списка аннотаций для поля. Смещение должно быть в разделе data . Формат данных определяется параметром « annotation_set_item » ниже. |
формат метод_аннотации
Имя | Формат | Описание |
---|---|---|
метод_idx | единица измерения | индекс в списке method_ids для идентификации аннотируемого метода |
аннотации_off | единица измерения | смещение от начала файла до списка аннотаций метода. Смещение должно быть в разделе data . Формат данных определяется параметром « annotation_set_item » ниже. |
формат параметра_аннотации
Имя | Формат | Описание |
---|---|---|
метод_idx | единица измерения | индекс в списке method_ids для идентификации метода, параметры которого аннотируются |
аннотации_off | единица измерения | смещение от начала файла до списка аннотаций для параметров метода. Смещение должно быть в разделе data . Формат данных определяется параметром « annotation_set_ref_list » ниже. |
annotation_set_ref_list
Ссылка на параметр_annotations_item
Появляется в разделе данных
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
размер | единица измерения | размер списка, в записях |
список | annotation_set_ref_item[размер] | элементы списка |
формат annotation_set_ref_item
Имя | Формат | Описание |
---|---|---|
аннотации_off | единица измерения | смещение от начала файла до указанного набора аннотаций или 0 , если для этого элемента нет аннотаций. Смещение, если оно не равно нулю, должно указывать на место в разделе data . Формат данных определяется параметром « annotation_set_item » ниже. |
annotation_set_item
Ссылка на annotations_directory_item, field_annotations_item, Method_annotations_item и annotation_set_ref_item
Появляется в разделе данных
Выравнивание: 4 байта
Имя | Формат | Описание |
---|---|---|
размер | единица измерения | размер набора, в записях |
записи | annotation_off_item[размер] | элементы набора. Элементы должны быть отсортированы в порядке возрастания по type_idx . |
формат annotation_off_item
Имя | Формат | Описание |
---|---|---|
аннотация_off | единица измерения | смещение от начала файла до аннотации. Смещение должно соответствовать местоположению в разделе data , а формат данных в этом месте определяется параметром « annotation_item » ниже. |
аннотация_элемент
Ссылка из annotation_set_item
Появляется в разделе данных
Выравнивание: нет (выровнено по байтам)
Имя | Формат | Описание |
---|---|---|
видимость | убайт | предполагаемая видимость этой аннотации (см. ниже) |
аннотация | закодированная_аннотация | закодированное содержимое аннотации в формате, описанном «форматом encoded_annotation » в разделе «кодирование encoded_value » выше. |
Значения видимости
Это параметры поля visibility
в annotation_item
:
Имя | Ценить | Описание |
---|---|---|
VISIBILITY_BUILD | 0x00 | предназначен только для того, чтобы быть видимым во время сборки (например, во время компиляции другого кода) |
VISIBILITY_RUNTIME | 0x01 | предназначен для просмотра во время выполнения |
VISIBILITY_SYSTEM | 0x02 | предназначен для просмотра во время выполнения, но только для базовой системы (а не для обычного пользовательского кода) |
encoded_array_item
Ссылка из class_def_item
Появляется в разделе данных
Выравнивание: нет (выровнено по байтам)
Имя | Формат | Описание |
---|---|---|
ценить | закодированный_массив | байты, представляющие закодированное значение массива, в формате, указанном «Форматом encoded_array » в разделе «Кодирование encoded_value » выше. |
скрытыйapi_class_data_item
Этот раздел содержит данные об ограниченных интерфейсах, используемых каждым классом.
Примечание. Функция скрытого API была представлена в Android 10.0 и применима только к файлам DEX классов в пути к классам загрузки. Список флагов, описанный ниже, может быть расширен в будущих выпусках Android. Дополнительные сведения см. в разделе ограничения на интерфейсы, не относящиеся к SDK .
Имя | Формат | Описание |
---|---|---|
размер | единица измерения | общий размер раздела |
смещения | uint[] | массив смещений, индексированных class_idx . Нулевая запись массива по индексу class_idx означает, что либо для этого class_idx нет данных, либо все скрытые флаги API равны нулю. В противном случае запись массива не равна нулю и содержит смещение от начала раздела до массива скрытых флагов API для этого class_idx . |
флаги | uleb128[] | объединенные массивы скрытых флагов API для каждого класса. Возможные значения флагов описаны в таблице ниже. Флаги кодируются в том же порядке, как поля и методы кодируются в данных класса. |
Типы флагов ограничения:
Имя | Ценить | Описание |
---|---|---|
белый список | 0 | Интерфейсы, которые можно свободно использовать и которые поддерживаются как часть официально документированного индекса пакетов платформы Android. |
серый список | 1 | Интерфейсы, не относящиеся к SDK, которые можно использовать независимо от целевого уровня API приложения. |
черный список | 2 | Интерфейсы, не относящиеся к SDK, которые нельзя использовать независимо от целевого уровня API приложения. Доступ к одному из этих интерфейсов вызывает ошибку времени выполнения . |
серый список-макс-о | 3 | Интерфейсы, не входящие в SDK, которые можно использовать для Android 8.x и более ранних версий, если они не ограничены. |
серый список-max-p | 4 | Интерфейсы, не относящиеся к SDK, которые можно использовать для Android 9.x, если они не ограничены. |
серый список-max-q | 5 | Интерфейсы, не входящие в SDK, которые можно использовать для Android 10.x, если на них нет ограничений. |
серый список-max-r | 6 | Интерфейсы, не входящие в SDK, которые можно использовать для Android 11.x, если они не ограничены. |
Системные аннотации
Системные аннотации используются для представления различных частей отражающей информации о классах (а также методах и полях). Доступ к этой информации обычно осуществляется только косвенно клиентским (несистемным) кодом.
Системные аннотации представлены в файлах .dex
как аннотации с видимостью, установленной на VISIBILITY_SYSTEM
.
dalvik.annotation.AnnotationDefault
Появляется в методах в интерфейсах аннотаций.
Аннотация AnnotationDefault
прикрепляется к каждому интерфейсу аннотаций, который хочет указать привязки по умолчанию.
Имя | Формат | Описание |
---|---|---|
ценить | Аннотация | привязки по умолчанию для этой аннотации, представленные как аннотация этого типа. Аннотация не обязательно должна включать все имена, определенные в ней; отсутствующие имена просто не имеют значений по умолчанию. |
dalvik.annotation.EnclosingClass
Появляется на занятиях
Аннотация EnclosingClass
прикрепляется к каждому классу, который либо определен как член другого класса сам по себе, либо является анонимным, но не определен в теле метода (например, синтетический внутренний класс). Каждый класс, имеющий эту аннотацию, также должен иметь аннотацию InnerClass
. Кроме того, класс не должен иметь одновременно аннотацию EnclosingClass
и EnclosingMethod
.
Имя | Формат | Описание |
---|---|---|
ценить | Сорт | класс, который наиболее точно лексически ограничивает этот класс |
dalvik.annotation.EnclosingMethod
Появляется на занятиях
Аннотация EnclosingMethod
прикрепляется к каждому классу, который определен внутри тела метода. Каждый класс, имеющий эту аннотацию, также должен иметь аннотацию InnerClass
. Кроме того, класс не должен иметь одновременно аннотацию EnclosingClass
и EnclosingMethod
.
Имя | Формат | Описание |
---|---|---|
ценить | Метод | метод, который наиболее точно лексически охватывает этот класс |
dalvik.annotation.InnerClass
Появляется на занятиях
Аннотация InnerClass
прикрепляется к каждому классу, который определен в лексической области определения другого класса. Любой класс, имеющий эту аннотацию , также должен иметь аннотацию EnclosingClass
или аннотацию EnclosingMethod
.
Имя | Формат | Описание |
---|---|---|
имя | Нить | первоначально объявленное простое имя этого класса (без префикса пакета). Если этот класс анонимный, то имя имеет значение null . |
AccessFlags | инт | первоначально объявленные флаги доступа класса (которые могут отличаться от действующих флагов из-за несоответствия моделей выполнения исходного языка и целевой виртуальной машины) |
dalvik.annotation.MemberClasses
Появляется на занятиях
Аннотация MemberClasses
прикрепляется к каждому классу, который объявляет классы-члены. (Класс-член — это прямой внутренний класс, имеющий имя.)
Имя | Формат | Описание |
---|---|---|
ценить | Сорт[] | массив классов-членов |
dalvik.annotation.MethodParameters
Появляется в методах
Примечание. Эта аннотация была добавлена после Android 7.1. Его присутствие в более ранних версиях Android будет игнорироваться.
Аннотация MethodParameters
является необязательной и может использоваться для предоставления метаданных параметров, таких как имена параметров и модификаторы.
Аннотацию можно безопасно исключить из метода или конструктора, если метаданные параметра не требуются во время выполнения. java.lang.reflect.Parameter.isNamePresent()
можно использовать для проверки наличия метаданных для параметра, а связанные методы отражения, такие как java.lang.reflect.Parameter.getName()
вернутся к поведению по умолчанию во время выполнения, если информация отсутствует.
При включении метаданных параметров компиляторы должны включать информацию для сгенерированных классов, таких как перечисления, поскольку метаданные параметра включают информацию о том, является ли параметр синтетическим или обязательным.
Аннотация MethodParameters
описывает только отдельные параметры метода. Поэтому компиляторы могут полностью опустить аннотацию для конструкторов и методов, не имеющих параметров, ради уменьшения размера кода и эффективности времени выполнения.
Массивы, описанные ниже, должны быть того же размера, что и структура dex method_id_item
, связанная с методом, в противном случае во время выполнения будет создано исключение java.lang.reflect.MalformedParametersException
.
То есть: method_id_item.proto_idx
-> proto_id_item.parameters_off
-> type_list.size
должен совпадать с names().length
и accessFlags().length
.
Поскольку MethodParameters
описывает все формальные параметры метода, даже те, которые не объявлены явно или неявно в исходном коде, размер массивов может отличаться от размера подписи или другой информации метаданных, основанной только на явных параметрах, объявленных в исходном коде. MethodParameters
также не будет включать какую-либо информацию о параметрах получателя аннотации типа, которые не существуют в фактической сигнатуре метода.
Имя | Формат | Описание |
---|---|---|
имена | Нить[] | Имена формальных параметров для связанного метода. Массив не должен быть нулевым, но должен быть пустым, если нет формальных параметров. Значение в массиве должно быть нулевым, если формальный параметр с этим индексом не имеет имени. Если строки имени параметра пусты или содержат '.', ';', '[' или '/', то во время выполнения будет создано исключение java.lang.reflect.MalformedParametersException . |
AccessFlags | интервал [] | Флаги доступа формальных параметров для связанного метода. Массив не должен быть нулевым, но должен быть пустым, если нет формальных параметров. Значение представляет собой битовую маску со следующими значениями:
java.lang.reflect.MalformedParametersException . |
dalvik.annotation.Signature
Появляется в классах, полях и методах.
Аннотация Signature
прикрепляется к каждому классу, полю или методу, который определен в терминах более сложного типа, чем тот, который может быть представлен type_id_item
. Формат .dex
не определяет формат подписей; он просто предназначен для представления любых сигнатур, которые требуются исходному языку для успешной реализации семантики этого языка. Таким образом, подписи обычно не анализируются (или не проверяются) реализациями виртуальных машин. Сигнатуры просто передаются API и инструментам более высокого уровня (например, отладчикам). Поэтому любое использование подписи должно быть написано так, чтобы не делать никаких предположений о получении только действительных подписей, явно защищая себя от возможности встретить синтаксически недействительную подпись.
Поскольку строки подписи, как правило, содержат много дублированного содержимого, аннотация Signature
определяется как массив строк, где дублированные элементы естественным образом относятся к одним и тем же базовым данным, а подпись считается конкатенацией всех строк в массиве. Не существует правил о том, как разделить подпись на отдельные строки; это полностью зависит от инструментов, генерирующих файлы .dex
.
Имя | Формат | Описание |
---|---|---|
ценить | Нить[] | подпись этого класса или члена в виде массива строк, которые должны быть объединены вместе |
dalvik.annotation.Выдает
Появляется в методах
Аннотация Throws
прикрепляется к каждому методу, который объявлен как создающий один или несколько типов исключений.
Имя | Формат | Описание |
---|---|---|
ценить | Сорт[] | массив выброшенных типов исключений |