Ограничения

Файл .dex – это формат передачи байт-кода Dalvik. Чтобы файл считался действительным файлом .dex, он должен соответствовать определенным синтаксическим и семантическим ограничениям .Кроме того, для поддержки действительных файлов DEX требуется среда выполнения.

Общие ограничения целостности DEX-файлов

Общие ограничения целостности относятся к структуре файла .dex, которая подробно описана в разделе Формат .dex.

Идентификатор Описание
G1 Номер magic файла .dex должен быть dex\n035\0 для версии 35 или аналогичным для более поздних версий.
G2 Контрольная сумма должна быть контрольной суммой Adler-32 всего содержимого файла, кроме полей magic и checksum.
Г3 Подпись должна представлять собой хеш SHA-1 всего содержимого файла, кроме magic, checksum и signature.
Г4

Значение file_size должно соответствовать фактическому размеру файла в байтах. (v40 или более ранние версии)

file_size должен указывать на следующий заголовок в контейнере или на конец физического файла (контейнера). Если он указывает на следующий заголовок, размер файла должен быть выровнен по 4 байтам. Сумма всех полей file_size должна быть равна container_size. (v41 или более поздняя версия)

Г5

Атрибут header_size должен иметь значение 0x70 (версия 40 или более ранняя).

Параметр header_size должен иметь значение 0x78. (версия 41 или более поздняя)

Г6 В поле endian_tag должно быть указано одно из следующих значений: ENDIAN_CONSTANT или REVERSE_ENDIAN_CONSTANT.
Г7

Для каждого из разделов link, string_ids, type_ids, proto_ids, field_ids, method_ids, class_defs и data поля offset и size должны быть либо оба нулевыми, либо оба ненулевыми. В последнем случае смещение должно быть выровнено по четырем байтам.

Поля offset и size должны находиться в контейнере и ссылаться на данные, которые расположены после заголовка, определяющего эти поля. (версия 41 или более поздняя)

G8 Все поля смещения в заголовке, кроме map_off, должны быть выровнены по четырем байтам.
Г9 Поле map_off должно быть равно нулю или указывать на раздел данных. В последнем случае раздел data должен существовать.
g10 Разделы link, string_ids, type_ids, proto_ids, field_ids, method_ids, class_defs и data не должны перекрывать друг друга или заголовок.
G11 Если карта существует, то каждая запись на ней должна иметь допустимый тип. Каждый тип может встречаться не более одного раза.
G12 Если карта существует, то в каждой записи карты должны быть ненулевые смещение и размер. Смещение должно указывать на соответствующий раздел файла (например, string_id_item должен указывать на раздел string_ids), а явный или неявный размер элемента должен соответствовать фактическому содержимому и размеру раздела.
G13 Если карта существует, то смещение записи карты n+1 должно быть больше или равно смещению записи карты n plus than size of map entry n. Это означает, что записи не должны пересекаться и должны быть упорядочены от меньшего к большему.
G14 Смещение следующих типов записей должно быть выровнено по четырем байтам: string_id_item, type_id_item, proto_id_item, field_id_item, method_id_item, class_def_item, type_list, code_item, annotations_directory_item.
G15

Для каждого элемента string_id_item поле string_data_off должно содержать действительную ссылку на раздел data. (v40 или более ранние версии)

Для каждого элемента string_id_item поле string_data_off должно быть смещением в контейнере и после любого заголовка, который его использует. (v41 или более поздняя версия)

Для параметра string_data_item поле data должно содержать действительную строку в кодировке MUTF-8, а значение поля utf16_size должно соответствовать декодированной длине строки.

G16 Для каждого объекта type_id_item поле descriptor_idx должно содержать действительную ссылку на список string_ids. Строка должна быть действительным дескриптором типа.
G17 Для каждого объекта proto_id_item поле shorty_idx должно содержать действительную ссылку на список string_ids. Указанная строка должна быть действительным дескриптором shorty. Кроме того, поле return_type_idx должно быть действительным индексом в разделе type_ids, а поле parameters_off должно быть либо нулевым, либо действительным смещением в разделе data. Если значение не равно нулю, список параметров не должен содержать пустых записей.
G18 Для каждого элемента field_id_item поля class_idx и type_idx должны быть действительными индексами в списке type_ids. Запись, на которую ссылается class_idx, должна быть ссылочного типа, не являющегося массивом. Кроме того, поле name_idx должно содержать действительную ссылку на раздел string_ids, а содержимое записи, на которую указывает ссылка, должно соответствовать спецификации MemberName.
G19 Для каждого элемента method_id_item поле class_idx должно быть допустимым индексом в разделе type_ids, а запись, на которую указывает ссылка, должна быть ссылочным типом, не являющимся массивом. Поле proto_id должно содержать действительную ссылку на список proto_ids. Поле name_idx должно содержать действительную ссылку на раздел string_ids, а содержимое записи, на которую указывает ссылка, должно соответствовать спецификации MemberName.
g20 Для каждого поля field_id_item поле class_idx должно быть действительным индексом в списке type_ids. Запись, на которую указывает ссылка, не должна быть ссылочным типом массива.

Ограничения на статический байт-код

Статические ограничения – это ограничения на отдельные элементы байт-кода. Обычно их можно проверить без использования методов анализа потока управления или данных.

Идентификатор Описание
A1 Массив insns не должен быть пустым.
A2 Первый код операции в массиве insns должен иметь индекс ноль.
A3 Массив insns должен содержать только действительные коды операций Dalvik.
A4 Индекс инструкции n+1 должен быть равен индексу инструкции n плюс длина инструкции n с учетом возможных операндов.
A5 Последняя инструкция в массиве insns должна заканчиваться на индексе insns_size-1.
A6 Все цели goto и if-<kind> должны быть кодами операций в одном и том же методе.
A7 Все цели инструкции packed-switch должны быть кодами операций в одном методе. Размер и список целевых значений должны быть согласованы.
A8 Все цели инструкции sparse-switch должны быть кодами операций в одном методе. Соответствующая таблица должна быть согласованной и отсортированной по возрастанию.
A9 Операнд B инструкций const-string и const-string/jumbo должен быть действительным индексом в пуле строковых констант.
A10 Операнд C инструкций iget<kind> и iput<kind> должен быть действительным индексом в пуле констант поля. Указанная запись должна представлять поле экземпляра.
A11 Операнд C инструкций sget<kind> и sput<kind> должен быть действительным индексом в пуле констант поля. Запись, на которую указывает ссылка, должна представлять статическое поле.
A12 Операнд C инструкций invoke-virtual, invoke-super, invoke-direct и invoke-static должен быть действительным индексом в пуле констант метода.
A13 Операнд B инструкций invoke-virtual/range, invoke-super/range, invoke-direct/range и invoke-static/range должен быть действительным индексом в пуле констант метода.
A14 Метод, название которого начинается с символа "<", может вызываться только неявно виртуальной машиной, а не кодом из файла .dex. Единственное исключение – инициализатор экземпляра, который может быть вызван invoke-direct.
A15 Операнд C инструкции invoke-interface должен быть действительным индексом в пуле констант метода. Указанный method_id должен принадлежать интерфейсу, а не классу.
A16 Операнд B инструкции invoke-interface/range должен быть действительным индексом в пуле констант метода. Указанный элемент method_id должен принадлежать интерфейсу (а не классу).
A17 Операнд B инструкций const-class, check-cast, new-instance и filled-new-array/range должен быть действительным индексом в пуле констант типа.
A18 Операнд C инструкций instance-of, new-array и filled-new-array должен быть действительным индексом в пуле констант типа.
A19 Размеры массива, созданного с помощью инструкции new-array, должны быть меньше 256.
A20 Инструкция new не должна ссылаться на классы массивов, интерфейсы или абстрактные классы.
A21 Тип, на который ссылается инструкция new-array, должен быть действительным и не должен быть ссылочным.
A22 Все регистры, на которые ссылается инструкция в одноширинном (непарном) режиме, должны быть действительны для текущего метода. Индексы должны быть неотрицательными и меньше registers_size.
A23 Все регистры, на которые ссылается инструкция в двойной ширине (паре), должны быть действительны для текущего метода. Их индексы должны быть неотрицательными и меньше registers_size-1.
A24 Операнд method_id инструкций invoke-virtual и invoke-direct должен принадлежать классу (не интерфейсу). В файлах Dex более ранних версий (до 037) это также относится к инструкциям invoke-super и invoke-static.
A25 Операнд method_id инструкций invoke-virtual/range и invoke-direct/range должен принадлежать классу (не интерфейсу). В файлах Dex более ранних версий (до 037) это также относится к инструкциям invoke-super/range и invoke-static/range.

Структурные ограничения на байт-код

Структурные ограничения – это ограничения на отношения между несколькими элементами байт-кода. Обычно их нельзя проверить без использования методов анализа управления или потока данных.

Идентификатор Описание
B1 Количество и типы аргументов (регистры и непосредственные значения) должны всегда соответствовать инструкции.
B2 Пары регистров нельзя разделять.
B3 Прежде чем читать регистр (или пару регистров), его необходимо назначить.
B4 Инструкция invoke-direct должна вызывать инициализатор экземпляра или метод только в текущем классе или одном из его надклассов.
B5 Инициализатор экземпляра должен вызываться только для неинициализированного экземпляра.
B6 Методы экземпляра могут вызываться только для уже инициализированных экземпляров, а поля экземпляра могут быть доступны только для них.
B7 Регистр, в котором хранится результат выполнения инструкции new-instance, нельзя использовать, если та же инструкция new-instance выполняется снова до инициализации экземпляра.
B8 Инициализатор экземпляра должен вызвать другой инициализатор экземпляра (того же класса или надкласса), прежде чем можно будет получить доступ к любым членам экземпляра. Исключение составляют ненаследуемые поля экземпляра, которые можно назначить до вызова другого инициализатора, и класс Object в целом.
B9 Все фактические аргументы метода должны быть совместимы по присваиванию со своими формальными аргументами.
B10 При каждом вызове метода экземпляра фактический экземпляр должен быть совместим по присваиванию с классом или интерфейсом, указанным в инструкции.
B11 Инструкция return<kind> должна соответствовать типу возвращаемого значения метода.
B12 При обращении к защищенным членам суперкласса фактический тип экземпляра должен быть текущим классом или одним из его подклассов.
B13 Тип значения, хранящегося в статическом поле, должен быть совместим с типом поля или преобразуем в него.
B14 Тип значения, хранящегося в поле, должен быть совместим с типом поля или преобразуемым в него.
B15 Тип каждого значения, хранящегося в массиве, должен быть совместим с типом компонента массива.
B16 Операнд A инструкции throw должен быть совместим с java.lang.Throwable по присваиванию.
B17 Последняя доступная инструкция метода должна быть инструкцией перехода назад goto или ветвления, return или throw. Нельзя, чтобы массив insns можно было покинуть снизу.
B18 Неназначенная половина бывшей пары регистров не может быть прочитана (считается недействительной), пока она не будет переназначена другой инструкцией.
B19 Инструкция move-result<kind> должна непосредственно предшествовать инструкции invoke-<kind> в массиве insns. Единственное исключение – инструкция move-result-object, перед которой может стоять инструкция filled-new-array.
B20 Инструкция move-result<kind> должна непосредственно предшествовать (в фактическом потоке управления) соответствующей инструкции return-<kind> (переход к ней недопустим). Единственное исключение – инструкция move-result-object, перед которой также может быть указана инструкция filled-new-array.
B21 Инструкция move-exception должна быть первой в обработчике исключений.
B22 Псевдоинструкции packed-switch-data, sparse-switch-data и fill-array-data не должны быть доступны для управления потоком.