Ограничения

Файл .dex — это транспортный формат для байт-кода Dalvik. Существуют определенные синтаксические и семантические ограничения для того, чтобы файл был допустимым файлом .dex , и среда выполнения должна поддерживать только допустимые файлы .dex.

Общие ограничения целостности .dex

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

Идентификатор Описание
Г1 magic число файла .dex должно быть dex\n035\0 или dex\n037\0 .
G2 Контрольная сумма должна быть контрольной суммой Adler-32 всего содержимого файла, за исключением magic поля и поля checksum .
G3 Подпись должна представлять собой хеш SHA-1 всего содержимого файла, за исключением magic , checksum и signature .
G4 file_size должен соответствовать фактическому размеру файла в байтах.
G5 header_size должен иметь значение: 0x70
G6 endian_tag должен иметь значение ENDIAN_CONSTANT или REVERSE_ENDIAN_CONSTANT .
G7 Для каждой из разделов link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs и data поля offset и size должны быть либо нулевыми, либо оба ненулевыми. В последнем случае смещение должно быть выровнено по четырем байтам.
G8 Все поля смещения в заголовке, кроме map_off должны быть выровнены по четырем байтам.
G9 Поле 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 . Для указанного string_data_item поле data должно содержать допустимую строку MUTF-8, а utf16_size должно соответствовать декодированной длине строки.
G16 Для каждого type_id_item поле descriptor_idx должно содержать действительную ссылку на список string_ids . Ссылочная строка должна быть допустимым дескриптором типа.
G17 Для каждого proto_id_item поле shorty_idx должно содержать действительную ссылку на список string_ids . Ссылочная строка должна быть допустимым коротким дескриптором. Кроме того, поле 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 . Ссылочная запись не должна быть ссылочным типом, отличным от массива.

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

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

Идентификатор Описание
А1 Массив insns не должен быть пустым.
А2 Первый код операции в массиве insns должен иметь нулевой индекс.
А3 Массив insns должен содержать только допустимые коды операций Dalvik.
А4 Индекс инструкции n+1 должен равняться индексу инструкции n плюс длине инструкции n с учетом возможных операндов.
А5 Последняя инструкция в массиве insns должна заканчиваться индексом insns_size-1 .
А6 Все цели goto и if-<kind> должны быть кодами операций одного и того же метода.
А7 Все цели инструкции packed-switch должны быть кодами операций одного и того же метода. Размер и список целей должны быть последовательными.
А8 Все цели инструкции sparse-switch должны быть кодами операций одного и того же метода. Соответствующая таблица должна быть последовательной и отсортированной по возрастанию.
А9 Операнд B инструкций const-string и const-string/jumbo должен быть допустимым индексом в пуле строковых констант.
А10 Операнд C инструкций iget<kind> и iput<kind> должен быть допустимым индексом в пуле констант полей. Ссылочная запись должна представлять поле экземпляра.
А11 Операнд C инструкций sget<kind> и sput<kind> должен быть допустимым индексом в пуле констант полей. Ссылочная запись должна представлять статическое поле.
А12 Операнд C инструкций invoke-virtual , invoke-super , invoke-direct и invoke-static должен быть допустимым индексом в пуле констант метода.
А13 Операнд B инструкций invoke-virtual/range , invoke-super/range , invoke-direct/range и invoke-static/range должен быть допустимым индексом в пуле констант метода.
А14 Метод, имя которого начинается с '<', должен вызываться только неявно виртуальной машиной, а не кодом, созданным из файла .dex . Единственным исключением является инициализатор экземпляра, который можно вызвать с помощью invoke-direct .
А15 Операнд C инструкции invoke-interface должен быть допустимым индексом в пуле констант метода. Ссылочный method_id должен принадлежать интерфейсу (а не классу).
А16 Операнд B инструкции invoke-interface/range должен быть допустимым индексом в пуле констант метода. Ссылочный method_id должен принадлежать интерфейсу (а не классу).
А17 Операнд B инструкций const-class , check-cast , new-instance и filled-new-array/range должен быть допустимым индексом в пуле констант типа.
А18 Операнд C инструкций instance-of , new-array и filled-new-array должен быть допустимым индексом в пуле констант типа.
А19 Размеры массива, созданного командой создания new-array должны быть меньше 256 .
А20 new инструкция не должна ссылаться на классы массивов, интерфейсы или абстрактные классы.
А21 Тип, на который ссылается инструкция создания new-array должен быть допустимым, не ссылочным типом.
А22 Все регистры, на которые ссылается инструкция одинарной ширины (не парные), должны быть допустимы для текущего метода. То есть их индексы должны быть неотрицательными и меньшими, чем registers_size .
А23 Все регистры, на которые ссылается инструкция в виде двойной ширины (пары), должны быть допустимы для текущего метода. То есть их индексы должны быть неотрицательными и меньше, чем registers_size-1 .
А24 Операнд method_id инструкций invoke-virtual и invoke-direct должен принадлежать классу (а не интерфейсу). В файлах Dex до версии 037 то же самое должно быть справедливо для инструкций invoke-super и invoke-static .
А25 Операнд method_id инструкций invoke-virtual/range и invoke-direct/range должен принадлежать классу (а не интерфейсу). В файлах Dex до версии 037 то же самое должно быть справедливо для инструкций invoke-super/range и invoke-static/range .

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

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

Идентификатор Описание
Б1 Количество и типы аргументов (регистры и непосредственные значения) всегда должны соответствовать инструкции.
Би 2 Пары регистров никогда не должны разбиваться.
Б3 Регистр (или пара) должен быть назначен первым, прежде чем его можно будет прочитать.
Б4 Инструкция invoke-direct должна вызывать инициализатор экземпляра или метод только в текущем классе или одном из его суперклассов.
Б5 Инициализатор экземпляра должен вызываться только для неинициализированного экземпляра.
Б6 Методы экземпляра можно вызывать только в экземплярах, а поля экземпляра доступны только в уже инициализированных экземплярах.
Б7 Регистр, в котором хранится результат инструкции new-instance не должен использоваться, если та же самая инструкция new-instance снова выполняется до инициализации экземпляра.
Б8 Инициализатор экземпляра должен вызвать другой инициализатор экземпляра (того же класса или суперкласса), прежде чем можно будет получить доступ к каким-либо членам экземпляра. Исключениями являются ненаследуемые поля экземпляра, которые можно назначить перед вызовом другого инициализатора, а также класс Object в целом.
Б9 Все фактические аргументы метода должны быть совместимы по присваиванию с соответствующими формальными аргументами.
Б10 Для каждого вызова метода экземпляра фактический экземпляр должен быть совместим по назначению с классом или интерфейсом, указанным в инструкции.
Б11 Инструкция return<kind> должна соответствовать типу возвращаемого значения своего метода.
Б12 При доступе к защищенным членам суперкласса фактический тип экземпляра, к которому осуществляется доступ, должен быть либо текущим классом, либо одним из его подклассов.
Б13 Тип значения, хранящегося в статическом поле, должен быть совместимым по присваиванию или конвертируемым в тип поля.
Б14 Тип значения, хранящегося в поле, должен быть совместимым по присваиванию или конвертируемым в тип поля.
Б15 Тип каждого значения, хранящегося в массиве, должен быть совместим по присваиванию с типом компонента массива.
Б16 Операнд A инструкции throw должен быть совместим по назначению с java.lang.Throwable .
Б17 Последняя достижимая инструкция метода должна быть либо инструкцией обратного goto или перехода, либо инструкцией return , либо инструкцией throw . Не должно быть возможности оставить массив insns внизу.
Б18 Неназначенная половина бывшей пары регистров не может быть прочитана (считается недействительной) до тех пор, пока она не будет переназначена какой-либо другой инструкцией.
Б19 Инструкции move-result<kind> должна предшествовать (в массиве insns ) инструкция invoke-<kind> . Единственным исключением является инструкция move-result-object , которой также может предшествовать инструкция filled-new-array .
Б20 Инструкции move-result<kind> должна предшествовать (в фактическом потоке управления) соответствующая инструкция return-<kind> (к ней нельзя переходить). Единственным исключением является инструкция move-result-object , которой также может предшествовать инструкция filled-new-array .
Б21 Инструкция move-exception должна появляться только в качестве первой инструкции в обработчике исключений.
Б22 Псевдоинструкции packed-switch-data , sparse-switch-data и fill-array-data не должны быть доступны для потока управления.