Формат исполняемого файла Dalvik

В этом документе описывается структура и содержимое файлов .dex , которые используются для хранения набора определений классов и связанных с ними дополнительных данных.

Руководство по типам

Имя Описание
байт 8-битное целое число со знаком
убайт 8-битное беззнаковое целое число
короткий 16-битное целое число со знаком, прямой порядок байтов
сокращать 16-битное беззнаковое целое число с прямым порядком байтов
интервал 32-битное целое число со знаком, прямой порядок байтов
uint 32-битное целое число без знака, с прямым порядком байтов
длинный 64-битное целое число со знаком, прямой порядок байтов
улонг 64-битное целое число без знака, с прямым порядком байтов
слеб128 подписан LEB128, переменной длины (см. ниже)
улеб128 беззнаковый LEB128, переменная длина (см. ниже)
улеб128п1 беззнаковый 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
-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 ) — это второстепенный порядок. Список не должен содержать повторяющихся записей.
идентификаторы метода метод_id_item[] список идентификаторов методов. Это идентификаторы всех методов, на которые ссылается этот файл, независимо от того, определены они в файле или нет. Этот список должен быть отсортирован, где определяющий тип (по индексу type_id ) — это основной порядок, имя метода (по индексу string_id ) — это промежуточный порядок, а прототип метода (по индексу proto_id ) — это второстепенный порядок. Список не должен содержать повторяющихся записей.
class_defs class_def_item[] список определений классов. Классы должны быть упорядочены таким образом, чтобы суперкласс данного класса и реализованные интерфейсы появлялись в списке раньше, чем ссылающийся класс. Более того, определение одного и того же класса недопустимо появляться в списке более одного раза.
call_site_ids call_site_id_item[] список идентификаторов сайтов вызовов. Это идентификаторы всех сайтов вызова, на которые ссылается этот файл, независимо от того, определены они в файле или нет. Этот список должен быть отсортирован в порядке возрастания call_site_off .
метод_handles метод_handle_item[] метод обрабатывает список. Список всех дескрипторов методов, на которые ссылается этот файл, независимо от того, определены они в файле или нет. Этот список не отсортирован и может содержать дубликаты, которые логически соответствуют различным экземплярам дескриптора метода.
данные убайт[] область данных, содержащая все вспомогательные данные для таблиц, перечисленных выше. Разные элементы имеют разные требования к выравниванию, и байты заполнения вставляются перед каждым элементом, если это необходимо для достижения правильного выравнивания.
ссылка_данные убайт[] данные, используемые в статически связанных файлах. Формат данных в этом разделе в этом документе не указан. Этот раздел пуст в несвязанных файлах, и реализации среды выполнения могут использовать его по своему усмотрению.

Определения битовых полей, строк и констант

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"

Примечание. Поддержка версии 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 имеет прямой порядок байтов, реализации могут выполнять замену байтов. Если реализация встретит заголовок, у которого endian_tag имеет REVERSE_ENDIAN_CONSTANT вместо ENDIAN_CONSTANT , она будет знать, что файл был заменен байтами из ожидаемой формы.

uint ENDIAN_CONSTANT = 0x12345678;
uint REVERSE_ENDIAN_CONSTANT = 0x78563412;

NO_INDEX

Встроен в 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 : виден пакету и подклассам
АКК_СТАТИК 0x8 * static : не создается с использованием внешней ссылки this static : глобально для определения класса static : не принимает this аргумент
ACC_FINAL 0x10 final : не подклассифицируется final : неизменяемый после создания final : не переопределяемый
АКК_СИНХРОНИЗИРОВАННЫЙ 0x20 synchronized : связанная блокировка автоматически устанавливается при вызове этого метода.

Примечание. Эту настройку можно устанавливать только в том случае, если также установлен ACC_NATIVE .

ACC_VOLATILE 0x40 volatile : специальные правила доступа, помогающие обеспечить потокобезопасность.
АКК_БРИДЖЕ 0x40 метод моста, автоматически добавляемый компилятором как типобезопасный мост
ACC_TRANSIENT 0x80 transient : не сохраняться при сериализации по умолчанию
ACC_VARARGS 0x80 последний аргумент должен рассматриваться компилятором как «остальный» аргумент
ACC_NATIVE 0x100 native : реализован в собственном коде
АКК_ИНТЕРФЕЙС 0x200 interface : многократно реализуемый абстрактный класс
ACC_ABSTRACT 0x400 abstract : невозможно создать экземпляр напрямую abstract : не реализовано в этом классе
ACC_STRICT 0x800 strictfp : строгие правила для арифметики с плавающей запятой.
АКК_СИНТЕТИЧЕСКИЙ 0x1000 не определено напрямую в исходном коде не определено напрямую в исходном коде не определено напрямую в исходном коде
АКК_АННОТАЦИЯ 0x2000 объявлен как класс аннотации
АКК_ЕНУМ 0x4000 объявлен как перечислимый тип объявлен как перечислимое значение
(не используется) 0x8000
АКК_КОНСТРУКТОР 0x10000 метод конструктора (инициализатор класса или экземпляра)
ACC_DECLARED_
СИНХРОНИЗИРОВАНО
0x20000 объявлен synchronized .

Примечание. Это не влияет на выполнение (кроме отражения этого флага как такового).

* Разрешено только для аннотаций InnerClass и никогда не должно быть включено в class_def_item .

Модифицированная кодировка UTF-8.

В качестве уступки упрощенной поддержке устаревших версий формат .dex кодирует строковые данные в стандартную модифицированную форму UTF-8, именуемую в дальнейшем MUTF-8. Эта форма идентична стандартной UTF-8, за исключением:

  • Используются только одно-, двух- и трехбайтовые кодировки.
  • Кодовые точки в диапазоне U+10000U+10ffff кодируются как суррогатная пара, каждая из которых представлена ​​как трехбайтовое закодированное значение.
  • Кодовая точка U+0000 кодируется в двухбайтовой форме.
  • Простой нулевой байт (значение 0 ) указывает на конец строки, как это принято в стандартной интерпретации языка C.

Первые два пункта выше можно резюмировать следующим образом: MUTF-8 — это формат кодировки UTF-16, а не более прямой формат кодирования символов Юникода.

Последние два пункта выше позволяют одновременно включать кодовую точку 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 — это закодированный фрагмент (почти) произвольных иерархически структурированных данных. Кодировка должна быть компактной и простой для анализа.

Имя Формат Описание
(значение_аргумент << 5) | тип значения убайт байт, указывающий тип следующего за ним value вместе с необязательным уточняющим аргументом в трех старших битах. Ниже приведены различные определения value . В большинстве случаев value_arg кодирует длину следующего value в байтах, как (size - 1) , например, 0 означает, что для значения требуется один байт, а 7 означает, что для него требуется восемь байтов; однако есть исключения, как указано ниже.
ценить убайт[] байты, представляющие значение, переменные по длине и интерпретируемые по-разному для разных байтов value_type , хотя всегда с прямым порядком байтов. Подробности см. в различных определениях значений ниже.

Форматы значений

Тип Имя value_type Формат value_arg Формат value Описание
VALUE_BYTE 0x00 (нет; должно быть 0 ) убайт[1] однобайтовое целое число со знаком
VALUE_SHORT 0x02 размер - 1 (0…1) убайт [размер] двухбайтовое целочисленное значение со знаком, расширенное знаком
VALUE_CHAR 0x03 размер - 1 (0…1) убайт [размер] беззнаковое двухбайтовое целое число, расширяемое нулем
VALUE_INT 0x04 размер - 1 (0…3) убайт [размер] четырехбайтовое целое число со знаком, расширенное знаком
VALUE_LONG 0x06 размер - 1 (0…7) убайт [размер] восьмибайтовое целое число со знаком, расширенное знаком
VALUE_FLOAT 0x10 размер - 1 (0…3) убайт [размер] четырехбайтовый битовый шаблон, расширенный до нуля вправо и интерпретируемый как 32-битное значение с плавающей запятой IEEE754.
VALUE_DOUBLE 0x11 размер - 1 (0…7) убайт [размер] восьмибайтовый битовый шаблон, расширенный до нуля вправо и интерпретируемый как 64-битное значение с плавающей запятой IEEE754.
VALUE_METHOD_TYPE 0x15 размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целочисленное значение, интерпретируемое как индекс в разделе proto_ids и представляющее значение типа метода.
VALUE_METHOD_HANDLE 0x16 размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целочисленное значение, интерпретируемое как индекс в разделе method_handles и представляющее значение дескриптора метода
VALUE_STRING 0x17 размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целое значение, интерпретируемое как индекс в разделе string_ids и представляющее строковое значение.
ТИП ЗНАЧЕНИЯ 0x18 размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целочисленное значение, интерпретируемое как индекс в разделе type_ids и представляющее отражающее значение типа/класса.
VALUE_FIELD 0x19 размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целочисленное значение, интерпретируемое как индекс в разделе field_ids и представляющее отражающее значение поля.
VALUE_METHOD 0x1а размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целочисленное значение, интерпретируемое как индекс в разделе method_ids и представляющее отражающее значение метода.
VALUE_ENUM 0x1b размер - 1 (0…3) убайт [размер] беззнаковое (расширенное нулем) четырехбайтовое целочисленное значение, интерпретируемое как индекс в разделе field_ids и представляющее значение константы перечисляемого типа.
VALUE_ARRAY 0x1c (нет; должно быть 0 ) закодированный_массив массив значений в формате, указанном в «формате encoded_array » ниже. Размер value неявно заложен в кодировке.
VALUE_ANNOTATION 0x1d (нет; должно быть 0 ) закодированная_аннотация дополнительная аннотация в формате, указанном в «формате encoded_annotation » ниже. Размер value неявно заложен в кодировке.
VALUE_NULL 0x1е (нет; должно быть 0 ) (никто) null опорное значение
VALUE_BOOLEAN 0x1f логическое значение (0…1) (никто) однобитовое значение; 0 для false и 1 для true . Бит представлен в value_arg .

формат закодированного_массива

Имя Формат Описание
размер улеб128 количество элементов в массиве
ценности закодированное_значение[размер] серия последовательностей байтов size encoded_value в формате, указанном в этом разделе, объединенных последовательно.

формат закодированной_аннотации

Имя Формат Описание
type_idx улеб128 тип аннотации. Это должен быть тип класса (а не массива или примитива).
размер улеб128 количество сопоставлений имени и значения в этой аннотации
элементы annotation_element[размер] элементы аннотации, представленные непосредственно в строке (а не в виде смещений). Элементы должны быть отсортированы в порядке возрастания индекса string_id .

формат annotation_element

Имя Формат Описание
name_idx улеб128 имя элемента, представленное как индекс в разделе string_ids . Строка должна соответствовать синтаксису MemberName , определенному выше.
ценить закодированное_значение значение элемента

Строковый синтаксис

В файле .dex есть несколько типов элементов, которые в конечном итоге относятся к строке. Следующие определения в стиле BNF указывают приемлемый синтаксис для этих строк.

Простое имя

SimpleName является основой синтаксиса имен других вещей. Формат .dex предоставляет здесь достаточную свободу действий (намного большую, чем большинство распространенных исходных языков). Короче говоря, простое имя состоит из любого буквенного символа или цифры младшего ASCII, нескольких конкретных символов младшего ASCII и большинства кодовых точек, отличных от ASCII, которые не являются управляющими, пробелами или специальными символами. Начиная с версии 040 формат дополнительно допускает пробелы (категория Unicode Zs ). Обратите внимание, что суррогатные кодовые точки (в диапазоне U+d800U+dfff ) не считаются допустимыми символами имени сами по себе, но допустимы дополнительные символы Unicode (которые представлены последней альтернативой правила для SimpleNameChar ), и они должны быть представлены в файле как пары суррогатных кодовых точек в кодировке MUTF-8.

ПростоеИмя
SimpleNameChar ( SimpleNameChar )*
ПростоеИмяСимвол
'A''Z'
| 'a''z'
| '0''9'
| ' ' начиная с версии DEX 040
| '$'
| '-'
| '_'
| U+00a0 начиная с версии DEX 040
| U+00a1U+1fff
| U+2000U+200a начиная с версии DEX 040
| U+2010U+2027
| U+202f начиная с версии DEX 040
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

Имя участника

используется field_id_item и Method_id_item

MemberName — это имя члена класса, членами которого являются поля, методы и внутренние классы.

Имя участника
Простое имя
| '<' ПростоеИмя '>'

ПолноеИмяКласса

FullClassName — это полное имя класса, включающее необязательный спецификатор пакета, за которым следует обязательное имя.

ПолноеИмяКласса
Необязательный префикс пакета SimpleName
Необязательный префикс пакета
( ПростоеИмя '/' )*

Типдескриптор

Используется type_id_item

TypeDescriptor — это представление любого типа, включая примитивы, классы, массивы и void . Ниже описано значение различных версий.

Дескриптор типа
'V'
| Полетипдескриптор
ПолеТипДескриптор
NonArrayFieldTypeDescriptor
| ( '[' * 1…255) NonArrayFieldTypeDescriptor
Дескриптор NonArrayFieldTypeDescriptor
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L' Имя полного класса ';'

КоротышкаДескриптор

Используется proto_id_item

ShortyDescriptor — это краткое представление прототипа метода, включая типы возвращаемых значений и параметров, за исключением того, что нет различия между различными типами ссылок (класс или массив). Вместо этого все ссылочные типы представлены одним символом 'L' .

КороткийДескриптор
ShortyReturnType ( ShortyFieldType )*
Тип возврата
'V'
| Коротыфилдтипе
КороткийФилдТип
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'

Семантика дескриптора типа

В этом смысл каждого из вариантов TypeDescriptor .

Синтаксис Значение
В void ; действительно только для возвращаемых типов
З boolean
Б byte
С short
С char
я int
Дж long
Ф float
Д double
L полностью/квалифицированный/имя ; класс fully.qualified.Name
[ дескриптор массив descriptor , который можно использовать рекурсивно для массивов массивов, хотя недопустимо иметь более 255 измерений.

Предметы и связанные структуры

В этом разделе приведены определения для каждого элемента верхнего уровня, который может присутствовать в файле .dex .

заголовок_элемент

Появляется в разделе заголовка

Выравнивание: 4 байта

Имя Формат Описание
магия убайт[8] = DEX_FILE_MAGIC магическое значение. Более подробную информацию смотрите в обсуждении выше в разделе « DEX_FILE_MAGIC ».
контрольная сумма uint adler32 контрольная сумма остальной части файла (все, кроме magic и этого поля); используется для обнаружения повреждения файлов
подпись убайт [20] Подпись SHA-1 (хеш) остальной части файла (все, кроме magic , checksum и этого поля); используется для уникальной идентификации файлов
размер файла uint размер всего файла (включая заголовок), в байтах
размер_заголовка уинт = 0x70 размер заголовка (весь этот раздел) в байтах. Это обеспечивает, по крайней мере, ограниченную обратную/прямую совместимость, не делая формат недействительным.
endian_tag uint = ENDIAN_CONSTANT тег порядка байтов. Дополнительные сведения см. выше в разделе « ENDIAN_CONSTANT и REVERSE_ENDIAN_CONSTANT ».
link_size uint размер раздела ссылки или 0 , если этот файл не связан статически
ссылка_off uint смещение от начала файла до раздела ссылки или 0 , если link_size == 0 . Смещение, если оно не равно нулю, должно соответствовать смещению в разделе link_data . Формат указанных данных в этом документе не указан; это поле заголовка (и предыдущее) остается в качестве перехватчиков для использования реализациями во время выполнения.
map_off uint смещение от начала файла до элемента карты. Смещение, которое должно быть ненулевым, должно соответствовать смещению в разделе data , а данные должны быть в формате, указанном в « map_list » ниже.
string_ids_size uint количество строк в списке идентификаторов строк
string_ids_off uint смещение от начала файла до списка идентификаторов строк или 0 , если string_ids_size == 0 (правда, странный крайний случай). Смещение, если оно не равно нулю, должно быть в начале раздела string_ids .
type_ids_size uint количество элементов в списке идентификаторов типов, не более 65535
type_ids_off uint смещение от начала файла до списка идентификаторов типов или 0 , если type_ids_size == 0 (правда, странный крайний случай). Смещение, если оно не равно нулю, должно быть в начале раздела type_ids .
proto_ids_size uint количество элементов в списке идентификаторов прототипа, не более 65535
proto_ids_off uint смещение от начала файла до списка идентификаторов прототипа или 0 , если proto_ids_size == 0 (правда, странный крайний случай). Смещение, если оно не равно нулю, должно быть в начале раздела proto_ids .
field_ids_size uint количество элементов в списке идентификаторов полей
field_ids_off uint смещение от начала файла до списка идентификаторов полей или 0 , если field_ids_size == 0 . Смещение, если оно не равно нулю, должно быть в начале раздела field_ids .
метод_ids_size uint количество элементов в списке идентификаторов метода
метод_ids_off uint смещение от начала файла до списка идентификаторов методов или 0 , если method_ids_size == 0 . Смещение, если оно не равно нулю, должно быть в начале раздела method_ids .
class_defs_size uint количество элементов в списке определений классов
class_defs_off uint смещение от начала файла до списка определений классов или 0 , если class_defs_size == 0 (правда, странный крайний случай). Смещение, если оно не равно нулю, должно быть в начале раздела class_defs .
размер_данных uint Размер раздела data в байтах. Должно быть кратно sizeof(uint).
data_off uint смещение от начала файла до начала раздела data .

список_карт

Появляется в разделе данных

Ссылка из header_item

Выравнивание: 4 байта

Это список всего содержимого файла по порядку. Он содержит некоторую избыточность по отношению к header_item , но задуман как простая форма для перебора всего файла. Данный тип должен появляться на карте не более одного раза, но нет никаких ограничений на то, в каком порядке могут появляться типы, кроме ограничений, подразумеваемых остальной частью формата (например, сначала должен появиться раздел header , а затем string_ids раздел и др.). Кроме того, записи карты должны быть упорядочены по начальному смещению и не должны перекрываться.

Имя Формат Описание
размер uint размер списка, в записях
список карта_элемент[размер] элементы списка

формат карты_элемента

Имя Формат Описание
тип сокращать тип предметов; см. таблицу ниже
неиспользованный сокращать (не используется)
размер uint подсчет количества элементов, которые можно найти по указанному смещению
компенсировать uint смещение от начала файла до рассматриваемых элементов

Типовые коды

Тип вещи Постоянный Ценить Размер элемента в байтах
заголовок_элемент 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
метод_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
метод_handle_item TYPE_METHOD_HANDLE_ITEM 0x0008 0x08
список_карт TYPE_MAP_LIST 0x1000 4 + (размер элемента * 12)
список_типов 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 скрытый; должен разобрать
code_item TYPE_CODE_ITEM 0x2001 скрытый; должен разобрать
string_data_item TYPE_STRING_DATA_ITEM 0x2002 скрытый; должен разобрать
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 скрытый; должен разобрать
аннотация_элемент TYPE_ANNOTATION_ITEM 0x2004 скрытый; должен разобрать
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 скрытый; должен разобрать
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 скрытый; должен разобрать
скрытыйapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 скрытый; должен разобрать

string_id_item

Появляется в разделе string_ids.

Выравнивание: 4 байта

Имя Формат Описание
string_data_off uint смещение от начала файла до строковых данных для этого элемента. Смещение должно быть в разделе data , а данные должны быть в формате, указанном в параметре « string_data_item » ниже. Для смещения не существует требований по выравниванию.

string_data_item

Появляется в разделе данных

Выравнивание: нет (выравнивание по байтам)

Имя Формат Описание
utf16_size улеб128 размер этой строки в кодовых единицах UTF-16 (что во многих системах является «длиной строки»). То есть это декодированная длина строки. (Закодированная длина определяется позицией 0 байта.)
данные убайт[] серия кодовых единиц MUTF-8 (также известных как октеты или байты), за которыми следует байт со значением 0 . Подробную информацию и обсуждение формата данных см. выше в разделе «Кодировка MUTF-8 (модифицированная UTF-8)».

Примечание. Допустимо иметь строку, которая включает (в закодированной форме) суррогатные кодовые единицы UTF-16 (то есть U+d800U+dfff ) либо изолированно, либо не по порядку по отношению к обычной кодировке. из Юникода в UTF-16. Отклонение таких недопустимых кодировок, если это необходимо, зависит от использования строк на более высоком уровне.

type_id_item

Появляется в разделе type_ids

Выравнивание: 4 байта

Имя Формат Описание
дескриптор_idx uint индекс в списке string_ids для строки дескриптора этого типа. Строка должна соответствовать синтаксису TypeDescriptor , определенному выше.

proto_id_item

Появляется в разделе proto_ids

Выравнивание: 4 байта

Имя Формат Описание
коротышка_idx uint индекс в списке string_ids для строки краткого дескриптора этого прототипа. Строка должна соответствовать синтаксису ShortyDescriptor , определенному выше, и должна соответствовать возвращаемому типу и параметрам этого элемента.
return_type_idx uint индекс в списке type_ids для возвращаемого типа этого прототипа
параметры_выкл. uint смещение от начала файла до списка типов параметров для этого прототипа или 0 , если этот прототип не имеет параметров. Это смещение, если оно не равно нулю, должно находиться в разделе data , а данные там должны быть в формате, указанном в "type_list" ниже. Кроме того, в списке не должно быть ссылок на тип void .

field_id_item

Появляется в разделе field_ids

Выравнивание: 4 байта

Имя Формат Описание
class_idx сокращать индекс в списке type_ids для определителя этого поля. Это должен быть тип класса, а не массив или примитивный тип.
type_idx сокращать индекс в списке type_ids для типа этого поля
name_idx uint индекс в списке string_ids для имени этого поля. Строка должна соответствовать синтаксису MemberName , определенному выше.

метод_id_item

Появляется в разделе Method_ids.

Выравнивание: 4 байта

Имя Формат Описание
class_idx сокращать индекс в списке type_ids для определяющего этого метода. Это должен быть тип класса или массива, а не примитивный тип.
proto_idx сокращать индекс в списке proto_ids для прототипа этого метода
name_idx uint индекс в списке string_ids для имени этого метода. Строка должна соответствовать синтаксису MemberName , определенному выше.

class_def_item

Появляется в разделе class_defs.

Выравнивание: 4 байта

Имя Формат Описание
class_idx uint индекс в список type_ids для этого класса. Это должен быть тип класса, а не массив или примитивный тип.
access_flags uint флаги доступа для класса ( public , final и т. д.). Подробности см. в разделе «Определения access_flags ».
суперкласс_idx uint индекс в списке type_ids для суперкласса или постоянное значение NO_INDEX , если у этого класса нет суперкласса (т. е. это корневой класс, такой как Object ). Если он присутствует, это должен быть тип класса, а не массив или примитивный тип.
интерфейсы_off uint смещение от начала файла до списка интерфейсов или 0 , если их нет. Это смещение должно находиться в разделе data , а данные там должны быть в формате, указанном в « type_list » ниже. Каждый из элементов списка должен быть типом класса (а не массивом или примитивным типом), и не должно быть дубликатов.
source_file_idx uint индекс в списке string_ids для имени файла, содержащего исходный источник (по крайней мере, большей части) этого класса, или специальное значение NO_INDEX , обозначающее отсутствие этой информации. debug_info_item любого данного метода может переопределить этот исходный файл, но ожидается, что большинство классов будут получены только из одного исходного файла.
аннотации_off uint смещение от начала файла до структуры аннотаций для этого класса или 0 , если для этого класса нет аннотаций. Это смещение, если оно не равно нулю, должно находиться в разделе data , а данные там должны быть в формате, указанном в « annotations_directory_item » ниже, причем все элементы ссылаются на этот класс как на определяющий.
class_data_off uint смещение от начала файла до связанных данных класса для этого элемента или 0 , если для этого класса нет данных класса. (Это может иметь место, например, если этот класс является интерфейсом маркера.) Смещение, если оно не равно нулю, должно находиться в разделе data , а данные там должны быть в формате, указанном в « class_data_item » ниже: все элементы ссылаются на этот класс как на определяющий.
static_values_off uint смещение от начала файла до списка начальных значений для 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 uint смещение от начала файла для вызова определения сайта. Смещение должно находиться в разделе данных, а данные там должны быть в формате, указанном в параметре «call_site_item» ниже.

call_site_item

Появляется в разделе данных

Выравнивание: нет (выровнено по байтам)

Call_site_item — это encoded_array_item, элементы которого соответствуют аргументам, предоставленным методу компоновщика начальной загрузки. Первые три аргумента:

  1. Дескриптор метода, представляющий метод компоновщика начальной загрузки (VALUE_METHOD_HANDLE).
  2. Имя метода, которое должен разрешить компоновщик начальной загрузки (VALUE_STRING).
  3. Тип метода, соответствующий типу имени метода, подлежащего разрешению (VALUE_METHOD_TYPE).

Любые дополнительные аргументы представляют собой постоянные значения, передаваемые методу компоновщика начальной загрузки. Эти аргументы передаются по порядку и без каких-либо преобразований типов.

Дескриптор метода, представляющий метод компоновщика начальной загрузки, должен иметь тип возвращаемого значения java.lang.invoke.CallSite . Первые три типа параметров:

  1. java.lang.invoke.Lookup
  2. java.lang.String
  3. java.lang.invoke.MethodType

Типы параметров любых дополнительных аргументов определяются по их постоянным значениям.

метод_handle_item

Появляется в разделе Method_handles.

Выравнивание: 4 байта

Имя Формат Описание
method_handle_type Ushort тип рукоятки метода; См. Таблицу ниже
неиспользованный Ushort (неиспользованный)
Field_or_method_id Ushort Идентификатор поля или метода в зависимости от того, является ли тип дескриптора метода аксессуаром или методом Invoker
неиспользованный Ushort (неиспользованный)

Коды типа метода

Постоянный Ценить Описание
Method_handle_type_static_put 0x00 Грандизатор метода является статическим сеттером поля (аксессуар)
Method_handle_type_static_get 0x01 Грандизатор метода является статическим полем Getter (аксессуар)
Method_handle_type_instance_put 0x02 Грандизатор метода - это установщик поля экземпляра (аксессуар)
Method_handle_type_instance_get 0x03 Грандизатор метода является получением поля экземпляра (аксессуар)
Method_handle_type_invoke_static 0x04 Грандизатор метода является статическим методом Invoker
Method_handle_type_invoke_instance 0x05 Грандизатор метода - это метод экземпляра Invoker
Method_handle_type_invoke_constructor 0x06 Грандизатор метода - это метод конструктора Invoker
Method_handle_type_invoke_direct 0x07 Грандизатор метода - это прямой метод Invoker
Method_handle_type_invoke_interface 0x08 Грандизатор метода - это метод интерфейса Invoker

class_data_item

Ссылка на class_def_item

Появляется в разделе данных

Выравнивание: нет (выровненная байтовая)

Имя Формат Описание
static_fields_size Uleb128 количество статических полей, определенных в этом элементе
exance_fields_size Uleb128 Количество полей экземпляра, определенных в этом элементе
direct_methods_size Uleb128 количество прямых методов, определенных в этом элементе
virtual_methods_size Uleb128 количество виртуальных методов, определенных в этом элементе
static_fields incoded_field [static_fields_size] Определенные статические поля, представленные как последовательность закодированных элементов. Поля должны быть отсортированы по field_idx в порядке увеличения.
exance_fields encoded_field [exance_fields_size] Определенные поля экземпляра, представленные как последовательность закодированных элементов. Поля должны быть отсортированы по field_idx в порядке увеличения.
Direct_methods incoded_method [direct_methods_size] Определенные прямые (любой из static , private или конструкторов) методов, представленные как последовательность кодируемых элементов. Методы должны быть отсортированы с помощью method_idx в увеличении порядка.
virtual_methods incoded_method [virtual_methods_size] Определенные виртуальные (ни один из static , private или конструкторов) методов, представленных как последовательность кодируемых элементов. Этот список не должен включать в себя унаследованные методы, если это не переоценка классом, который представляет этот элемент. Методы должны быть отсортированы с помощью method_idx в увеличении порядка. method_idx виртуального метода не должен быть таким же, как и любой прямой метод.

Примечание. Все экземпляры Elements ' field_id и method_id должны относиться к одному и тому же определяющему классу.

Формат кодировки

Имя Формат Описание
Field_idx_diff Uleb128 Индекс в список field_ids для идентификации этого поля (включает имя и дескриптор), представленного как отличие от индекса предыдущего элемента в списке. Индекс первого элемента в списке представлен напрямую.
access_flags Uleb128 Флаги доступа для поля ( public , final и т. Д.). См. «Определения access_flags » для получения подробной информации.

Кодированный формат

Имя Формат Описание
method_idx_diff Uleb128 ИНДЕКС В СПИСОК method_ids для идентификации этого метода (включает имя и дескриптор), представленного как отличие от индекса предыдущего элемента в списке. Индекс первого элемента в списке представлен напрямую.
access_flags Uleb128 Флаги доступа к методу ( public , final и т. Д.). См. «Определения access_flags » для получения подробной информации.
code_off Uleb128 Смещение от начала файла в структуру кода для этого метода, или 0 , если этот метод либо abstract , либо native . Смещение должно быть в месте в разделе data . Формат данных указан « code_item » ниже.

type_list

Ссылка на Class_def_item и Proto_id_item

Появляется в разделе данных

Выравнивание: 4 байта

Имя Формат Описание
размер uint размер списка, в записях
список type_item [размер] элементы списка

формат type_item

Имя Формат Описание
type_idx Ushort Индекс в список type_ids

code_item

Ссылка на кодировку

Появляется в разделе данных

Выравнивание: 4 байта

Имя Формат Описание
registers_size Ushort количество регистров, используемых этим кодом
ins_size Ushort количество слов входящих аргументов по методу, для которого предназначен этот код
outs_size Ushort количество слов исходящего пространства аргументов, необходимых для этого кода для вызова метода
tries_size Ushort Количество try_item S для этого экземпляра. Если ненулевые, то они появляются в качестве массива tries сразу после insns в этом случае.
DEBUG_INFO_OFF uint Смещение от начала файла в последовательность «Информация отладки» (номера строк + локальная информация переменной) для этого кода, или 0 , если просто нет информации. Смещение, если он не нулевой, должно быть в месте в разделе data . Формат данных указан « debug_info_item » ниже.
insns_size uint размер списка инструкций, в 16-битных кодовых единицах
Insns Ushort [insns_size] Фактический массив байт -кода. Формат кода в массиве insns указывается компаньоном Dalvik Bytecode . Обратите внимание, что, хотя это определяется как массив ushort , есть некоторые внутренние структуры, которые предпочитают четырех байтов. Кроме того, если это оказывается в файле с эндсианом, то обмен выполняется только на отдельных экземплярах ushort , а не на более крупных внутренних структурах.
прокладка Ushort (необязательно) = 0 Два байта прокладки, чтобы сделать tries четырех байтовых. Этот элемент присутствует только в том случае, если tries_size не нулевой, а insns_size нечетный.
пытается try_item [tries_size] (необязательно) массив, указывающий, где в коде исключения пойманы и как их обрабатывать. Элементы массива должны быть непересекающимися в диапазоне и по порядку от низкого до высокого адреса. Этот элемент присутствует только в том случае, если tries_size является ненулевым.
обработчики incoded_catch_handler_list (необязательно) Байты, представляющие список списков типов улова и связанных адресов обработчика. Каждый try_item имеет байтовое смещение в эту структуру. Этот элемент присутствует только в том случае, если tries_size является ненулевым.

Format try_item

Имя Формат Описание
start_addr uint Начальный адрес блока кода, охваченного этой записью. Адрес представляет собой подсчет 16-битных кодовых единиц для начала первой охватываемой инструкции.
insn_count Ushort Количество 16-битных кодовых единиц, охватываемых этой записью. Последний код, покрытый (включительно), start_addr + insn_count - 1 .
handler_off Ushort смещено в байтах с начала связанного encoded_catch_hander_list в encoded_catch_handler для этой записи. Это должно быть смещением к началу encoded_catch_handler .

Encoded_catch_handler_list Format

Имя Формат Описание
размер Uleb128 размер этого списка, в записях
список incoded_catch_handler [handlers_size] Фактический список списков обработчиков, представленных непосредственно (не как смещения) и последовательно

Encoded_catch_handler Format

Имя Формат Описание
размер SLEB128 Количество типов уловов в этом списке. Если не положительный, то это отрицательно от количества типов улова, а за уловками следует обработчик с уловами. Например: size 0 означает, что есть все, но нет явно напечатанных уловов. size 2 означает, что есть два явных напечатанных улова и нет всех. А size -1 означает, что есть один типичный улов вместе с всеобъемлющим.
обработчики incoded_type_addr_pair [abs (size)] Поток предметов abs(size) , кодируемых, по одному для каждого пойманного типа, в порядке, чтобы типы должны быть проверены.
catch_all_addr Uleb128 (необязательно) БАЙДЕКОДНЫЙ АДРЕС УДОВАЯ ОБРАЗОВАНИЯ. Этот элемент присутствует только в том случае, если size не является положительным.

incoded_type_addr_pair формат

Имя Формат Описание
type_idx Uleb128 индекс в список type_ids для типа исключения, чтобы поймать
адрес Uleb128 Адрес по байт -коде соответствующего обработчика исключений

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 Uleb128 Начальное значение для регистра line штата. Не представляет фактическую запись позиций.
параметры_size Uleb128 Количество имен параметров, которые закодированы. Должен быть один параметр для метода, исключая метод экземпляра, если this имеются.
Parameter_names uleb128p1 [parameters_size] Строковой индекс имени параметра метода. Кодированное значение 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 Register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num : регистр, который будет содержать локальный
name_idx : индекс строки имени
type_idx : индекс типа типа
Представляет локальную переменную по текущему адресу. Либо name_idx или type_idx может быть NO_INDEX , чтобы указать, что это значение неизвестно.
Dbg_start_local_extended 0x04 uleb128 Register_num
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 , однако, те же данные могут быть представлены более эффективно, используя OPCODE DBG_START_LOCAL .)

ПРИМЕЧАНИЕ. См. Обсуждение в разделе « dalvik.annotation.Signature » ниже для предостережения об обращении с подписями.

Dbg_end_local 0x05 uleb128 Register_num register_num : регистр, который содержал локальный Оценка локальной переменной в настоящее время в настоящее время не в текущем адресе
Dbg_restart_local 0x06 uleb128 Register_num register_num : зарегистрироваться для перезапуска Повторно вводит локальную переменную по текущему адресу. Название и тип такие же, как последний локальный, который жил в указанном реестре.
Dbg_set_prologue_end 0x07 (никто) Устанавливает регистр машины prologue_end State, указывая, что добавленная запись следующей позиции следует рассматривать конец пролога метода (подходящее место для точки останова метода). Регистр prologue_end очищается любым специальным ( >= 0x0a ) Opcode.
DBG_SET_EPILOGE_BEGIN 0x08 (никто) Устанавливает регистр машины epilogue_begin State Machine, указывая, что добавленная запись следующей позиции должна рассматриваться как начало эпилога метода (подходящее место для приостановки выполнения перед выходом метода). Регистр epilogue_begin очищается любым специальным ( >= 0x0a ) OPCODE.
Dbg_set_file 0x09 uleb128p1 name_idx name_idx : индекс String исходного файла; 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 uint Смещение от начала файла в аннотации, сделанные непосредственно в классе, или 0 , если у класса нет прямых аннотаций. Смещение, если он не нулевой, должно быть в месте в разделе data . Формат данных указан « annotation_set_item » ниже.
fields_size uint Подсчет полей, аннотированных этим предметом
Annotated_methods_size uint Подсчет методов, аннотированных этим предметом
Annotated_Parameters_size uint Подсчет параметров метода перечисляет аннотированный этим элементом
Field_annotations Field_annotation [fields_size] (необязательно) Список связанных полевых аннотаций. Элементы списка должны быть отсортированы в порядке увеличения, по field_idx .
method_annotations method_annotation [methods_size] (необязательно) Список связанных методов аннотаций. Элементы списка должны быть отсортированы в порядке увеличения, по method_idx .
Parameter_annotations parameter_annotation [parameters_size] (необязательно) СПИСОК АННОТАЦИИ ПАРАМЕТАЦИИ МЕТОДА. Элементы списка должны быть отсортированы в порядке увеличения, по method_idx .

Примечание. Все экземпляры Elements ' field_id и method_id должны относиться к одному и тому же определяющему классу.

Field_annotation Format

Имя Формат Описание
Field_idx uint индекс в список field_ids для аннотированного идентификации поля
Annotations_off uint смещено с начала файла в список аннотаций для поля. Смещение должно быть в месте в разделе data . Формат данных указан « annotation_set_item » ниже.

method_annotation format

Имя Формат Описание
method_idx uint индекс в список method_ids для идентификации аннотированного метода
Annotations_off uint смещено с начала файла в список аннотаций для метода. Смещение должно быть в месте в разделе data . Формат данных указан « annotation_set_item » ниже.

FARATER_ANNOTATION FORMAT

Имя Формат Описание
method_idx uint Индекс в список method_ids для идентификации метода, параметры которых аннотируются
Annotations_off uint смещено с начала файла в список аннотаций для параметров метода. Смещение должно быть в месте в разделе data . Формат данных указывается « annotation_set_ref_list » ниже.

Annotation_set_ref_list

Ссылка на Parameter_annotations_item

Появляется в разделе данных

Выравнивание: 4 байта

Имя Формат Описание
размер uint размер списка, в записях
список annotation_set_ref_item [size] элементы списка

Annotation_set_ref_item Format

Имя Формат Описание
Annotations_off uint Смещение от начала файла в набор аннотаций с указанием или 0 , если для этого элемента нет аннотаций. Смещение, если он не нулевой, должно быть в месте в разделе data . Формат данных указан « annotation_set_item » ниже.

Annotation_set_item

Ссылка на Annotations_directory_item, Field_annotations_item, method_annotations_item и Annotation_set_ref_item

Появляется в разделе данных

Выравнивание: 4 байта

Имя Формат Описание
размер uint размер набора, в записях
записи Annotation_off_item [размер] элементы набора. Элементы должны быть отсортированы в увеличении порядка, по type_idx .

Annotation_off_item Format

Имя Формат Описание
Annotation_off uint смещено от начала файла в аннотацию. Смещение должно быть в месте в разделе data , а формат данных в этом месте указывается « annotation_item » ниже.

Annotation_Item

Ссылка на Annotation_set_item

Появляется в разделе данных

Выравнивание: нет (выровненная байтовая)

Имя Формат Описание
видимость Ubyte Предполагаемая видимость этой аннотации (см. Ниже)
аннотация кодировка_аннотации Кодированное содержимое аннотации, в формате, описанном в « 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 » выше.

hiddenapi_class_data_item

Этот раздел содержит данные о ограниченных интерфейсах, используемых каждым классом.

ПРИМЕЧАНИЕ. Функция скрытой API была введена в Android 10.0 и применима только к файлам DEX классов в пути класса загрузки. Список флагов, описанных ниже, может быть расширен в будущих выпусках Android. Для получения дополнительной информации см. Ограничения на не-SDK-интерфейсы .

Имя Формат Описание
размер uint Общий размер секции
смещения uint [] Массив смещений, индексируемый class_idx . Запись с нулевым массивом в индексе class_idx означает, что либо нет данных для этого class_idx , либо все скрытые флаги API равны нулю. В противном случае запись массива не нулевой и содержит смещение от начала раздела до массива скрытых флагов API для этого class_idx .
флаги Uleb128 [] Согласованные массивы скрытых флагов API для каждого класса. Возможные значения флага описаны в таблице ниже. Флаги кодируются в том же порядке, что и поля, а методы кодируются в данных класса.

Ограничение типы флага:

Имя Ценить Описание
белый список 0 Интерфейсы, которые могут быть свободно использованы и поддерживаются как часть официально документированного индекса пакета Android Framework.
СЕРИЙСКИЙ СЛИБ 1 Не-SDK интерфейсы, которые можно использовать независимо от целевого уровня API приложения.
черный список 2 Не-SDK интерфейсы, которые не могут быть использованы независимо от целевого уровня API приложения. Доступ к одному из этих интерфейсов вызывает ошибку времени выполнения .
Greylist -Max -O 3 Не-SDK интерфейсы, которые можно использовать для Android 8.x и ниже, если они не ограничены.
Greylist -Max -P 4 Не-SDK интерфейсы, которые можно использовать для Android 9.x, если они не ограничены.
Greylist -Max -Q 5 Не-SDK интерфейсы, которые можно использовать для Android 10.x, если они не ограничены.
Greylist -Max -R 6 Не-SDK интерфейсы, которые можно использовать для Android 11.x, если они не ограничены.

Системные аннотации

Системные аннотации используются для представления различных фрагментов рефлексивной информации о классах (и методах и полях). Эта информация, как правило, доступна только косвенно по клиентскому (несистемному) коду.

Системные аннотации представлены в файлах .dex в виде аннотаций с видимостью, установленными на VISIBILITY_SYSTEM .

dalvik.annotation.annotationdefault

Появляется на методах в интерфейсах аннотации

Аннотация AnnotationDefault прикреплена к каждому интерфейсу аннотации, который хочет указать привязки по умолчанию.

Имя Формат Описание
ценить Аннотация Привязки по умолчанию для этой аннотации представлены как аннотация этого типа. Аннотация не должна включать все имена, определенные аннотацией; Пропущенные имена просто не имеют по умолчанию.

dalvik.annotation.inclosingclass

Появляется на классах

Аннотация EnclosingClass прилагается к каждому классу, который либо определяется как член другого класса, как таковой, либо анонимна, но не определяется в теле метода (например, синтетический внутренний класс). Каждый класс, у которого есть эта аннотация, также должен иметь аннотацию InnerClass . Кроме того, класс не должен иметь как EnclosingClass , так и аннотацию EnclosingMethod .

Имя Формат Описание
ценить Сорт Класс, который наиболее близко квалифицирует этот класс

dalvik.annotation.inclosingmethod

Появляется на классах

Аннотация 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 int [] Флаги доступа формальных параметров для связанного метода. Массив не должен быть нулевым, но должен быть пустым, если нет формальных параметров.
Значение немного маски со следующими значениями:
  • 0x0010: окончательно, параметр был объявлен окончательным
  • 0x1000: синтетический, параметр был введен компилятором
  • 0x8000: Мандарный, параметр является синтетическим, но также подразумевается спецификацией языка
Если какие -либо биты установлены за пределами этого набора, то java.lang.reflect.MalformedParametersException будет брошен во время выполнения.

Dalvik.annotation.Signature

Появляется на классах, полях и методах

Аннотация Signature прикреплена к каждому классу, полю или методу, который определяется в терминах более сложного типа, чем представляется type_id_item . Формат .dex не определяет формат для подписей; Он просто предназначен для того, чтобы иметь возможность представлять любые подписи, которые требуют исходного языка для успешной реализации семантики этого языка. Таким образом, подписи, как правило, не проанализируются (или проверяются) с помощью реализаций виртуальных машин. Подписи просто передаются API и инструментам более высокого уровня (например, отладчики). Следовательно, любое использование подписи должно быть написано, чтобы не делать никаких предположений о получении только действительных подписей, явных охраняющихся от возможности столкновения с синтаксически недействительной.

Поскольку строки подписи, как правило, имеют много дублированного контента, аннотация Signature определяется как массив строк, где дублированные элементы естественным образом относятся к одни и те же основные данные, и подпись рассматривается как сознание всех строк в массиве . Нет никаких правил о том, как разместить подпись в отдельные строки; Это полностью зависит от инструментов, которые генерируют файлы .dex .

Имя Формат Описание
ценить Нить[] Подпись этого класса или члена, как множество струн, которые должны быть объединены вместе

dalvik.annotation.throws

Появляется на методах

Аннотация Throws прикреплена к каждому методу, который объявляется, чтобы бросить один или несколько типов исключений.

Имя Формат Описание
ценить Сорт[] массив типов исключений