Plik .dex
to format transportowy kodu bajtowego Dalvik. Istnieją pewne ograniczenia składniowe i semantyczne, aby plik był prawidłowym plikiem .dex
, a do obsługi tylko prawidłowych plików .dex wymagane jest środowisko wykonawcze.
Ogólne ograniczenia integralności .dex
Ogólne ograniczenia integralności dotyczą większej struktury pliku .dex
, jak opisano szczegółowo w formacie .dex
.
Identyfikator | Opis |
---|---|
G1 | magic liczba pliku .dex musi być dex\n035\0 lub dex\n037\0 . |
G2 | Suma kontrolna musi być sumą kontrolną Adler-32 całej zawartości pliku z wyjątkiem pola magic i checksum . |
G3 | Podpis musi być skrótem SHA-1 całej zawartości pliku z wyjątkiem magic , checksum i signature . |
G4 | file_size musi odpowiadać rzeczywistemu rozmiarowi pliku w bajtach. |
G5 | header_size musi mieć wartość: 0x70 |
G6 | endian_tag musi mieć wartość: ENDIAN_CONSTANT lub REVERSE_ENDIAN_CONSTANT |
G7 | Dla każdego link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs i sekcji data pola offset i size muszą mieć wartość zerową lub różną od zera. W tym drugim przypadku przesunięcie musi być wyrównane do czterech bajtów. |
G8 | Wszystkie pola przesunięcia w nagłówku, z wyjątkiem map_off muszą być wyrównane do czterech bajtów. |
G9 | Pole map_off musi mieć wartość zero lub wskazywać sekcję danych. W tym drugim przypadku sekcja data musi istnieć. |
G10 | Żaden z link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs i sekcji data nie może nakładać się na siebie ani na nagłówek. |
G11 | Jeśli mapa istnieje, każdy wpis mapy musi mieć prawidłowy typ. Każdy typ może wystąpić najwyżej raz. |
G12 | Jeśli mapa istnieje, każdy wpis mapy musi mieć niezerowe przesunięcie i rozmiar. Przesunięcie musi wskazywać odpowiednią sekcję pliku (tzn. string_id_item musi wskazywać sekcję string_ids ), a jawny lub ukryty rozmiar elementu musi odpowiadać rzeczywistej zawartości i rozmiarowi sekcji. |
G13 | Jeżeli mapa istnieje, to przesunięcie wpisu mapy n+1 musi być większe lub równe przesunięciu wpisu mapy n plus than size of map entry n . Oznacza to, że wpisy nie nakładają się na siebie i są uporządkowane od najniższego do najwyższego. |
G14 | Następujące typy wpisów muszą mieć offset wyrównany do czterech bajtów: 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 | Dla każdego string_id_item pole string_data_off musi zawierać prawidłowe odwołanie do sekcji data . W przypadku przywoływanego string_data_item pole data musi zawierać prawidłowy ciąg MUTF-8, a utf16_size musi odpowiadać zdekodowanej długości ciągu. |
G16 | Dla każdego type_id_item pole descriptor_idx musi zawierać prawidłowe odwołanie do listy string_ids . Ciąg, do którego następuje odwołanie, musi być prawidłowym deskryptorem typu. |
G17 | Dla każdego proto_id_item pole shorty_idx musi zawierać prawidłowe odwołanie do listy string_ids . Ciąg, do którego następuje odwołanie, musi być prawidłowym krótkim deskryptorem. Ponadto pole return_type_idx musi być prawidłowym indeksem sekcji type_ids , a pole parameters_off musi mieć wartość zero lub prawidłowe przesunięcie wskazujące sekcję data . Jeśli jest różna od zera, lista parametrów nie może zawierać żadnych pustych wpisów. |
G18 | Dla każdego field_id_item oba pola class_idx i type_idx muszą być prawidłowymi indeksami na liście type_ids . Wpis, do którego odwołuje się class_idx musi być typem odwołania innym niż tablica. Ponadto pole name_idx musi stanowić prawidłowe odwołanie do sekcji string_ids , a zawartość wpisu, do którego się odwołuje, musi być zgodna ze specyfikacją MemberName . |
G19 | Dla każdego method_id_item pole class_idx musi być prawidłowym indeksem w sekcji type_ids , a wpis, do którego się odwołuje, musi być typem referencyjnym innym niż tablicowy. Pole proto_id musi być prawidłowym odniesieniem do listy proto_ids . Pole name_idx musi być prawidłowym odniesieniem do sekcji string_ids , a zawartość wpisu, do którego się odwołuje, musi być zgodna ze specyfikacją MemberName . |
G20 | Dla każdego field_id_item pole class_idx musi być prawidłowym indeksem na liście type_ids . Wpis, do którego następuje odwołanie, musi być typem odniesienia innym niż tablicowy. |
Statyczne ograniczenia kodu bajtowego
Ograniczenia statyczne to ograniczenia nałożone na poszczególne elementy kodu bajtowego. Zwykle można je sprawdzić bez stosowania technik kontroli lub analizy przepływu danych.
Identyfikator | Opis |
---|---|
A1 | Tablica insns nie może być pusta. |
A2 | Pierwszy kod operacji w tablicy insns musi mieć indeks zero. |
A3 | Tablica insns musi zawierać tylko prawidłowe kody operacji Dalvik. |
A4 | Indeks instrukcji n+1 musi być równy indeksowi instrukcji n plus długość instrukcji n , biorąc pod uwagę możliwe argumenty. |
A5 | Ostatnia instrukcja w tablicy insns musi kończyć się indeksem insns_size-1 . |
A6 | Wszystkie cele goto i if-<kind> muszą być kodami operacji w ramach tej samej metody. |
A7 | Wszystkie cele instrukcji packed-switch muszą być kodami operacji w ramach tej samej metody. Rozmiar i lista celów muszą być spójne. |
A8 | Wszystkie cele instrukcji sparse-switch muszą być kodami operacji w ramach tej samej metody. Odpowiednia tabela musi być spójna i posortowana od najniższej do najwyższej. |
A9 | Operand B instrukcji const-string i const-string/jumbo musi być prawidłowym indeksem puli stałych łańcuchowych. |
A10 | Operand C instrukcji iget<kind> i iput<kind> musi być poprawnym indeksem puli stałych pola. Wpis, do którego następuje odwołanie, musi reprezentować pole instancji. |
A11 | Operand C instrukcji sget<kind> i sput<kind> musi być poprawnym indeksem puli stałych pola. Wpis, do którego następuje odwołanie, musi reprezentować pole statyczne. |
A12 | Operand C instrukcji invoke-virtual , invoke-super , invoke-direct i invoke-static musi być prawidłowym indeksem w puli stałych metod. |
A13 | Operand B instrukcji invoke-virtual/range , invoke-super/range , invoke-direct/range i invoke-static/range musi być prawidłowym indeksem w puli stałych metod. |
A14 | Metoda, której nazwa zaczyna się od znaku „<”, może zostać wywołana tylko pośrednio przez maszynę wirtualną, a nie przez kod pochodzący z pliku .dex . Jedynym wyjątkiem jest inicjator instancji, który może zostać wywołany przez invoke-direct . |
A15 | Operand C instrukcji invoke-interface musi być prawidłowym indeksem w puli stałych metod. Odwoływany method_id musi należeć do interfejsu (nie do klasy). |
A16 | Operand B instrukcji invoke-interface/range musi być prawidłowym indeksem w puli stałych metody. Odwoływany method_id musi należeć do interfejsu (nie do klasy). |
A17 | Operand B instrukcji const-class , check-cast , new-instance i filled-new-array/range musi być prawidłowym indeksem puli stałych typów. |
A18 | Operand C instrukcji instance-of , new-array i filled-new-array musi być prawidłowym indeksem puli stałych typów. |
A19 | Wymiary tablicy utworzonej za pomocą instrukcji new-array muszą być mniejsze niż 256 . |
A20 | new instrukcja nie może odnosić się do klas tablicowych, interfejsów ani klas abstrakcyjnych. |
A21 | Typ, do którego odwołuje się instrukcja new-array musi być prawidłowym typem, który nie jest typem referencyjnym. |
A22 | Wszystkie rejestry, do których odwołuje się instrukcja w trybie o pojedynczej szerokości (nieparowej), muszą być ważne dla bieżącej metody. Oznacza to, że ich indeksy muszą być nieujemne i mniejsze niż registers_size . |
A23 | Wszystkie rejestry, do których odnosi się instrukcja w trybie podwójnej szerokości (pary), muszą być ważne dla bieżącej metody. Oznacza to, że ich indeksy muszą być nieujemne i mniejsze niż registers_size-1 . |
A24 | Operand method_id instrukcji invoke-virtual i invoke-direct musi należeć do klasy (nie do interfejsu). W plikach Dex wcześniejszych niż wersja 037 to samo musi dotyczyć instrukcji invoke-super i invoke-static . |
A25 | Operand method_id instrukcji invoke-virtual/range i invoke-direct/range musi należeć do klasy (nie do interfejsu). W plikach Dex wcześniejszych niż wersja 037 to samo musi dotyczyć instrukcji invoke-super/range i invoke-static/range . |
Strukturalne ograniczenia kodu bajtowego
Ograniczenia strukturalne to ograniczenia relacji między kilkoma elementami kodu bajtowego. Zwykle nie można ich sprawdzić bez zastosowania technik kontroli lub analizy przepływu danych.
Identyfikator | Opis |
---|---|
B1 | Liczba i typy argumentów (rejestry i wartości bezpośrednie) muszą zawsze odpowiadać instrukcji. |
B2 | Pary rejestrów nie mogą być nigdy rozdzielane. |
B3 | Rejestr (lub para) musi zostać najpierw przypisany, zanim będzie można go odczytać. |
B4 | Instrukcja invoke-direct musi wywołać inicjator instancji lub metodę tylko w bieżącej klasie lub jednej z jej nadklas. |
B5 | Inicjator instancji musi być wywoływany tylko w przypadku niezainicjowanej instancji. |
B6 | Metody instancji można wywoływać tylko na instancjach, a dostęp do pól instancji można uzyskać tylko na instancjach już zainicjowanych. |
B7 | Rejestru przechowującego wynik instrukcji new-instance nie można używać, jeśli ta sama instrukcja new-instance zostanie wykonana ponownie przed inicjalizacją instancji. |
B8 | Inicjator instancji musi wywołać inny inicjator instancji (ta sama klasa lub nadklasa), zanim będzie można uzyskać dostęp do elementów członkowskich instancji. Wyjątkami są niedziedziczone pola instancji, które można przypisać przed wywołaniem innego inicjatora, oraz ogólnie klasa Object . |
B9 | Wszystkie rzeczywiste argumenty metod muszą być zgodne z przypisaniem z ich odpowiednimi argumentami formalnymi. |
B10 | Dla każdego wywołania metody instancji rzeczywista instancja musi być zgodna z przypisaniem z klasą lub interfejsem określonym w instrukcji. |
B11 | Instrukcja return<kind> musi odpowiadać typowi zwracanemu przez jej metodę. |
B12 | Podczas uzyskiwania dostępu do chronionych elementów nadklasy rzeczywistym typem instancji, do której uzyskuje się dostęp, musi być albo bieżąca klasa, albo jedna z jej podklas. |
B13 | Typ wartości przechowywanej w polu statycznym musi być zgodny z przypisaniem lub konwertowalny na typ pola. |
B14 | Typ wartości przechowywanej w polu musi być zgodny z przypisaniem lub konwertowalny na typ pola. |
B15 | Typ każdej wartości przechowywanej w tablicy musi być zgodny z przypisaniem z typem komponentu tablicy. |
B16 | Operand A instrukcji throw musi być kompatybilny z java.lang.Throwable . |
B17 | Ostatnią osiągalną instrukcją metody musi być instrukcja goto lub rozgałęzienia wstecz, instrukcja return lub instrukcja throw . Nie może być możliwe pozostawienie tablicy insns na dole. |
B18 | Nieprzypisana połowa poprzedniej pary rejestrów nie może zostać odczytana (jest uważana za nieważną), dopóki nie zostanie ponownie przypisana przez jakąś inną instrukcję. |
B19 | Instrukcja move-result<kind> musi być bezpośrednio poprzedzona (w tablicy insns ) instrukcją invoke-<kind> . Jedynym wyjątkiem jest instrukcja move-result-object , która może być również poprzedzona instrukcją filled-new-array . |
B20 | Instrukcja move-result<kind> musi być bezpośrednio poprzedzona (w rzeczywistym przepływie sterowania) pasującą instrukcją return-<kind> (nie wolno do niej przechodzić). Jedynym wyjątkiem jest instrukcja move-result-object , która może być również poprzedzona instrukcją filled-new-array . |
B21 | Instrukcja move-exception musi pojawić się tylko jako pierwsza instrukcja w procedurze obsługi wyjątku. |
B22 | Pseudoinstrukcje packed-switch-data , sparse-switch-data i fill-array-data nie mogą być osiągalne przez przepływ sterowania. |