Format pliku wykonywalnego Dalvik

W tym dokumencie opisano układ i zawartość plików .dex , które służą do przechowywania zestawu definicji klas i powiązanych z nimi danych dodatkowych.

Przewodnik po typach

Nazwa Opis
bajt 8-bitowy ze znakiem int
ubajt 8-bitowy int bez znaku
krótki 16-bitowy int ze znakiem, Little-Endian
skrócić 16-bitowy int bez znaku, Little-Endian
wew 32-bitowy int ze znakiem, Little-Endian
uint 32-bitowy int bez znaku, Little-Endian
długi 64-bitowy int ze znakiem, Little-Endian
ulong 64-bitowy int bez znaku, Little-Endian
sleb128 sygn. LEB128, zmienna długość (patrz niżej)
uleb128 bez znaku LEB128, o zmiennej długości (patrz poniżej)
uleb128p1 bez znaku LEB128 plus 1 , zmienna długość (patrz poniżej)

LEB128

LEB128 („ Little - Endian Base 128 ”) to kodowanie o zmiennej długości dla dowolnych liczb całkowitych ze znakiem lub bez znaku. Format został zapożyczony ze specyfikacji DWARF3 . W pliku .dex LEB128 jest używany tylko do kodowania ilości 32-bitowych.

Każda wartość zakodowana w LEB128 składa się z jednego do pięciu bajtów, które razem reprezentują pojedynczą wartość 32-bitową. Każdy bajt ma ustawiony najbardziej znaczący bit, z wyjątkiem ostatniego bajtu w sekwencji, dla którego najbardziej znaczący bit jest wolny. Pozostałe siedem bitów każdego bajtu to ładunek, przy czym najmniej znaczące siedem bitów ilości znajduje się w pierwszym bajcie, kolejnych siedem w drugim bajcie i tak dalej. W przypadku znaku LEB128 ( sleb128 ) najbardziej znaczący bit ładunku ostatniego bajtu w sekwencji jest rozszerzany znakiem w celu uzyskania wartości końcowej. W przypadku bez znaku ( uleb128 ) wszelkie bity, które nie są jawnie reprezentowane, są interpretowane jako 0 .

Diagram bitowy dwubajtowej wartości LEB128
Pierwszy bajt Drugi bajt
1 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 0 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 bit 7

Wariant uleb128p1 służy do reprezentowania wartości ze znakiem, gdzie reprezentacja jest wartością plus jeden zakodowaną jako uleb128 . To sprawia, że ​​kodowanie -1 (alternatywnie uważanej za wartość bez znaku 0xffffffff ) — ale żadnej innej liczby ujemnej — jest pojedynczym bajtem i jest przydatne dokładnie w tych przypadkach, gdy reprezentowana liczba musi być albo nieujemna, albo -1 (lub 0xffffffff ) i gdzie nie są dozwolone żadne inne wartości ujemne (lub gdzie jest mało prawdopodobne, aby potrzebne były duże wartości bez znaku).

Oto kilka przykładów formatów:

Zakodowana sekwencja Jak sleb128 Jak uleb128 Jak uleb128p1
00 0 0 -1
01 1 1 0
7f -1 127 126
80 7f -128 16256 16255

Układ pliku

Nazwa Format Opis
nagłówek element nagłówka Nagłówek
string_ids string_id_item[] lista identyfikatorów ciągów. Są to identyfikatory wszystkich ciągów znaków używanych przez ten plik, albo do wewnętrznego nazewnictwa (np. deskryptory typów), albo jako obiekty stałe, do których odwołuje się kod. Lista ta musi być posortowana według zawartości ciągów znaków, przy użyciu wartości kodowych UTF-16 (nie w sposób uwzględniający ustawienia regionalne) i nie może zawierać żadnych zduplikowanych wpisów.
identyfikatory typu typ_id_item[] lista identyfikatorów typów. Są to identyfikatory wszystkich typów (klas, tablic lub typów pierwotnych), do których odwołuje się ten plik, niezależnie od tego, czy są one zdefiniowane w pliku, czy nie. Lista ta musi być posortowana według indeksu string_id i nie może zawierać żadnych zduplikowanych wpisów.
proto_ids proto_id_item[] lista identyfikatorów prototypów metod. Są to identyfikatory wszystkich prototypów, do których odnosi się ten plik. Lista ta musi być posortowana według typu zwracanego (według indeksu type_id ), a następnie według listy argumentów (kolejność leksykograficzna, poszczególne argumenty uporządkowane według indeksu type_id ). Lista nie może zawierać żadnych duplikatów wpisów.
identyfikatory pól element_id_pola[] lista identyfikatorów pól. Są to identyfikatory wszystkich pól, do których odwołuje się ten plik, niezależnie od tego, czy są one zdefiniowane w pliku, czy nie. Ta lista musi być posortowana, gdzie typ definiujący (według indeksu type_id ) jest porządkiem głównym, nazwa pola (według indeksu string_id ) jest porządkiem pośrednim, a typ (według indeksu type_id ) jest porządkiem drugorzędnym. Lista nie może zawierać żadnych duplikatów wpisów.
identyfikatory metod metoda_id_item[] lista identyfikatorów metod. Są to identyfikatory wszystkich metod, do których odwołuje się ten plik, niezależnie od tego, czy są one zdefiniowane w pliku, czy nie. Ta lista musi być posortowana, gdzie typ definiujący (według indeksu type_id ) jest porządkiem głównym, nazwa metody (według indeksu string_id ) jest porządkiem pośrednim, a prototyp metody (według indeksu proto_id ) jest porządkiem drugorzędnym. Lista nie może zawierać żadnych duplikatów wpisów.
klasa_defs klasa_def_item[] lista definicji klas. Klasy muszą być tak uporządkowane, aby nadklasa i zaimplementowane interfejsy danej klasy pojawiały się na liście wcześniej niż klasa odsyłająca. Ponadto niedopuszczalne jest, aby definicja klasy o tej samej nazwie pojawiała się na liście więcej niż raz.
call_site_ids call_site_id_item[] wywołaj listę identyfikatorów witryn. Są to identyfikatory wszystkich stron wywołań, do których odnosi się ten plik, niezależnie od tego, czy są one zdefiniowane w pliku, czy nie. Ta lista musi być posortowana rosnąco według call_site_off .
uchwyty_metody metoda_uchwytu_item[] metoda obsługuje listę. Lista wszystkich uchwytów metod, do których odwołuje się ten plik, niezależnie od tego, czy są one zdefiniowane w pliku, czy nie. Lista ta nie jest posortowana i może zawierać duplikaty, które będą logicznie odpowiadać różnym instancjom uchwytów metod.
dane ubajt[] obszar danych, zawierający wszystkie dane pomocnicze dla tabel wymienionych powyżej. Różne elementy mają różne wymagania dotyczące wyrównania, a bajty dopełniające są wstawiane przed każdym elementem, jeśli jest to konieczne, aby osiągnąć prawidłowe wyrównanie.
dane_linku ubajt[] dane używane w plikach połączonych statycznie. W niniejszym dokumencie format danych w tej sekcji nie jest określony. Ta sekcja jest pusta w przypadku niepołączonych plików i implementacje środowiska wykonawczego mogą z niej korzystać według własnego uznania.

Definicje pól bitowych, łańcuchów i stałych

DEX_FILE_MAGIC

Osadzone w header_item

Stała tablica/łańcuch DEX_FILE_MAGIC to lista bajtów, które muszą pojawić się na początku pliku .dex , aby został on rozpoznany jako taki. Wartość celowo zawiera znak nowej linii ( "\n" lub 0x0a ) i bajt zerowy ( "\0" lub 0x00 ), aby pomóc w wykryciu określonych form korupcji. Wartość koduje również numer wersji formatu w postaci trzech cyfr dziesiętnych, przy czym oczekuje się, że liczba ta będzie z biegiem czasu monotonicznie rosnąć w miarę ewolucji formatu.

ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 }
                        = "dex\n039\0"

Uwaga: w wersji Androida 9.0 dodano obsługę wersji 039 formatu, która wprowadziła dwa nowe kody bajtowe: const-method-handle i const-method-type . (Każdy z nich opisano w tabeli Podsumowanie zestawów kodów bajtowych ). W systemie Android 10 wersja 039 rozszerza format pliku DEX, aby uwzględnić ukryte informacje API, które mają zastosowanie tylko do plików DEX w ścieżce klasy rozruchowej.

Uwaga: w wersji Androida 8.0 dodano obsługę wersji 038 formatu. Wersja 038 dodała nowe kody bajtowe ( invoke-polymorphic i invoke-custom ) oraz dane dla uchwytów metod.

Uwaga: w wersji Androida 7.0 dodano obsługę wersji 037 formatu. Przed wersją 037 większość wersji Androida korzystała z wersji 035 formatu. Jedyną różnicą pomiędzy wersjami 035 i 037 jest dodanie metod domyślnych i dostosowanie invoke .

Uwaga: co najmniej kilka wcześniejszych wersji tego formatu było używanych w powszechnie dostępnych publicznych wydaniach oprogramowania. Na przykład wersja 009 była używana w wydaniach M3 platformy Android (listopad – grudzień 2007), a wersja 013 była używana w wydaniach M5 platformy Android (luty – marzec 2008). Pod kilkoma względami te wcześniejsze wersje formatu różnią się znacznie od wersji opisanej w tym dokumencie.

ENDIAN_CONSTANT i REVERSE_ENDIAN_CONSTANT

Osadzone w header_item

Stała ENDIAN_CONSTANT służy do wskazania endianowości pliku, w którym się znajduje. Chociaż standardowym formatem .dex jest Little-Endian, implementacje mogą zdecydować się na wykonanie zamiany bajtów. Jeśli implementacja napotka nagłówek, którego endian_tag ma REVERSE_ENDIAN_CONSTANT zamiast ENDIAN_CONSTANT , będzie wiedzieć, że plik został zamieniony bajtami z oczekiwanej formy.

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

NO_INDEX

Osadzone w class_def_item i debug_info_item

Stała NO_INDEX służy do wskazania braku wartości indeksu.

Uwaga: ta wartość nie jest zdefiniowana jako 0 , ponieważ w rzeczywistości jest to zazwyczaj prawidłowy indeks.

Wybrana wartość NO_INDEX jest reprezentowana jako pojedynczy bajt w kodowaniu uleb128p1 .

uint NO_INDEX = 0xffffffff;    // == -1 if treated as a signed int

definicje flag_dostępu

Osadzone w class_def_item, encoded_field, encoded_method i InnerClass

Pola bitowe tych flag służą do wskazania dostępności i ogólnych właściwości klas i członków klas.

Nazwa Wartość Dla klas (i adnotacji InnerClass ) Dla Fieldsa Dla metod
ACC_PUBLIC 0x1 public : widoczne wszędzie public : widoczne wszędzie public : widoczne wszędzie
ACC_PRIVATE 0x2 * private : widoczny tylko dla definiującej klasy private : widoczny tylko dla definiującej klasy private : widoczny tylko dla definiującej klasy
ACC_PROTECTED 0x4 * protected : widoczne dla pakietu i podklas protected : widoczne dla pakietu i podklas protected : widoczne dla pakietu i podklas
ACC_STATIC 0x8 * static : nie jest skonstruowany z zewnętrznym odwołaniem this static : globalny do definiowania klasy static : nie przyjmuje this argumentu
ACC_FINAL 0x10 final : nie podlega podklasie final : niezmienny po zakończeniu konstrukcji final : nie do zastąpienia
ACC_SYNCHRONIZOWANY 0x20 synchronized : powiązana blokada uzyskiwana automatycznie po wywołaniu tej metody.

Uwaga: Można to ustawić tylko wtedy, gdy ustawiono również ACC_NATIVE .

ACC_VOLATILE 0x40 volatile : specjalne reguły dostępu pomagające w bezpieczeństwie wątków
ACC_BRIDGE 0x40 metoda mostu, dodawana automatycznie przez kompilator jako most bezpieczny dla typu
ACC_TRANSIENT 0x80 transient : nie jest zapisywany przez domyślną serializację
ACC_VARARGS 0x80 ostatni argument powinien być traktowany przez kompilator jako argument „reszta”.
ACC_NATIVE 0x100 native : zaimplementowany w kodzie natywnym
ACC_INTERFACE 0x200 interface : klasa abstrakcyjna, którą można wielokrotnie implementować
ACC_ABSTRACT 0x400 abstract : nie można bezpośrednio utworzyć abstract : niezaimplementowane w tej klasie
ACC_STRICT 0x800 strictfp : ścisłe zasady arytmetyki zmiennoprzecinkowej
ACC_SYNTHETIC 0x1000 nie zdefiniowane bezpośrednio w kodzie źródłowym nie zdefiniowane bezpośrednio w kodzie źródłowym nie zdefiniowane bezpośrednio w kodzie źródłowym
ACC_ANNOTATION 0x2000 zadeklarowana jako klasa adnotacji
ACC_ENUM 0x4000 zadeklarowany jako typ wyliczeniowy zadeklarowana jako wartość wyliczeniowa
(nie używany) 0x8000
ACC_CONSTRUCTOR 0x10000 metoda konstruktora (inicjator klasy lub instancji)
ACC_DECLARED_
Zsynchronizowane
0x20000 zadeklarowany synchronized .

Uwaga: nie ma to wpływu na wykonanie (z wyjątkiem odzwierciedlenia tej flagi jako takiej).

* Dozwolona tylko w przypadku adnotacji InnerClass i nigdy nie może być włączona w class_def_item .

Zmodyfikowane kodowanie UTF-8

W ramach ustępstwa na rzecz łatwiejszej obsługi starszych wersji, format .dex koduje dane w postaci ciągów znaków w de facto standardowej zmodyfikowanej formie UTF-8, zwanej dalej MUTF-8. Formularz ten jest identyczny ze standardowym UTF-8, z wyjątkiem:

  • Stosowane jest tylko kodowanie jedno-, dwu- i trzybajtowe.
  • Punkty kodowe z zakresu U+10000U+10ffff są kodowane jako para zastępcza, z których każdy jest reprezentowany jako zakodowana wartość trzybajtowa.
  • Punkt kodowy U+0000 jest kodowany w postaci dwubajtowej.
  • Zwykły bajt zerowy (wartość 0 ) wskazuje koniec łańcucha, zgodnie ze standardową interpretacją języka C.

Pierwsze dwa powyższe elementy można podsumować w następujący sposób: MUTF-8 to format kodowania dla UTF-16, zamiast być bardziej bezpośrednim formatem kodowania znaków Unicode.

Ostatnie dwa elementy powyżej umożliwiają jednoczesne włączenie punktu kodowego U+0000 do ciągu i nadal manipulowanie nim jako ciągiem zakończonym zerem w stylu C.

Jednak specjalne kodowanie U+0000 oznacza, że ​​w przeciwieństwie do zwykłego UTF-8, wynik wywołania standardowej funkcji C strcmp() na parze ciągów MUTF-8 nie zawsze wskazuje poprawnie podpisany wynik porównania nierównych ciągów . Gdy problemem jest kolejność (nie tylko równość), najprostszym sposobem porównania ciągów MUTF-8 jest dekodowanie ich znak po znaku i porównanie zdekodowanych wartości. (Jednak możliwe są również bardziej sprytne implementacje.)

Więcej informacji na temat kodowania znaków można znaleźć w dokumencie Standard Unicode . MUTF-8 jest w rzeczywistości bliższy (stosunkowo mniej znanemu) kodowaniu CESU-8 niż UTF-8 jako takiemu.

kodowanie wartości_kodowanej

Osadzone w annotation_element i encoded_array_item

encoded_value to zakodowany fragment (prawie) dowolnych danych o strukturze hierarchicznej. Kodowanie ma być zarówno zwarte, jak i łatwe do analizy.

Nazwa Format Opis
(argument_wartości << 5) | typ wartości ubajt bajt wskazujący typ bezpośrednio następującej value wraz z opcjonalnym argumentem wyjaśniającym w trzech bitach wyższego rzędu. Poniżej znajdują się różne definicje value . W większości przypadków value_arg koduje długość bezpośrednio następującej po niej value w bajtach, jako (size - 1) , np. 0 oznacza, że ​​wartość wymaga jednego bajtu, a 7 oznacza, że ​​wymaga ośmiu bajtów; jednakże istnieją wyjątki, jak opisano poniżej.
wartość ubajt[] bajty reprezentujące wartość, o zmiennej długości i różnie interpretowane dla różnych bajtów value_type , chociaż zawsze Little-endian. Aby uzyskać szczegółowe informacje, zobacz różne definicje wartości poniżej.

Formaty wartości

Wpisz imię value_type value_arg Format format value Opis
WARTOŚĆ_BAJT 0x00 (brak; musi wynosić 0 ) ubajt[1] jednobajtowa wartość całkowita ze znakiem
WARTOŚĆ_SKRÓT 0x02 rozmiar - 1 (0…1) ubajt [rozmiar] Dwubajtowa wartość całkowita ze znakiem, z rozszerzeniem znaku
WARTOŚĆ_ZNAK 0x03 rozmiar - 1 (0…1) ubajt [rozmiar] dwubajtowa wartość całkowita bez znaku, rozszerzona o zero
WARTOŚĆ_INT 0x04 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita ze znakiem, z rozszerzeniem znaku
WARTOŚĆ_DŁUGA 0x06 rozmiar - 1 (0…7) ubajt [rozmiar] Ośmiobajtowa wartość całkowita ze znakiem, z rozszerzeniem znaku
WARTOŚĆ_FLOAT 0x10 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowy wzór bitowy, zerem przedłużonym w prawo i interpretowany jako 32-bitowa wartość zmiennoprzecinkowa IEEE754
WARTOŚĆ_DOUBLE 0x11 rozmiar - 1 (0…7) ubajt [rozmiar] ośmiobajtowy wzór bitowy, zerem przedłużonym w prawo i interpretowany jako 64-bitowa wartość zmiennoprzecinkowa IEEE754
VALUE_METHOD_TYPE 0x15 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita bez znaku (rozszerzona o zero), interpretowana jako indeks w sekcji proto_ids i reprezentująca wartość typu metody
VALUE_METHOD_HANDLE 0x16 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita bez znaku (rozszerzona o zero), interpretowana jako indeks w sekcji method_handles i reprezentująca wartość uchwytu metody
WARTOŚĆ_STRING 0x17 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita bez znaku (rozszerzona o zero), interpretowana jako indeks w sekcji string_ids i reprezentująca wartość ciągu znaków
TYP WARTOŚCI 0x18 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita bez znaku (rozszerzona o zero), interpretowana jako indeks w sekcji type_ids i reprezentująca odblaskową wartość typu/klasy
POLE WARTOŚCI 0x19 rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita bez znaku (rozszerzona o zero), interpretowana jako indeks w sekcji field_ids i reprezentująca odblaskową wartość pola
METODA_WARTOŚCI 0x1a rozmiar - 1 (0…3) ubajt [rozmiar] czterobajtowa wartość całkowita bez znaku (rozszerzona o zero), interpretowana jako indeks w sekcji method_ids i reprezentująca odblaskową wartość metody
WARTOŚĆ_ENUM 0x1b rozmiar - 1 (0…3) ubajt [rozmiar] unsigned (rozszerzona o zero) czterobajtowa wartość całkowita, interpretowana jako indeks w sekcji field_ids i reprezentująca wartość stałej typu wyliczeniowego
WARTOŚĆ_TABLICA 0x1c (brak; musi wynosić 0 ) zakodowana_tablica tablica wartości w formacie określonym w „formacie encoded_array ” poniżej. Rozmiar value jest ukryty w kodowaniu.
WARTOŚĆ_ANOTACJA 0x1d (brak; musi wynosić 0 ) zakodowana_adnotacja adnotacja podrzędna w formacie określonym w „formacie encoded_annotation ” poniżej. Rozmiar value jest ukryty w kodowaniu.
WARTOŚĆ_NULL 0x1e (brak; musi wynosić 0 ) (nic) wartość referencyjna null
WARTOŚĆ_BOOLEAN 0x1f wartość logiczna (0…1) (nic) wartość jednobitowa; 0 dla false i 1 dla true . Bit jest reprezentowany w value_arg .

format zakodowanej_tablicy

Nazwa Format Opis
rozmiar uleb128 liczba elementów tablicy
wartości zakodowana_wartość[rozmiar] seria sekwencji bajtów size encoded_value w formacie określonym w tej sekcji, połączonych sekwencyjnie.

format zakodowanej_adnotacji

Nazwa Format Opis
typ_idx uleb128 rodzaj adnotacji. Musi to być typ klasy (nie tablicowy lub pierwotny).
rozmiar uleb128 liczba odwzorowań nazwa-wartość w tej adnotacji
elementy element_adnotacji[rozmiar] elementy adnotacji, reprezentowane bezpośrednio w linii (nie jako przesunięcia). Elementy muszą być posortowane w kolejności rosnącej według indeksu string_id .

format elementu adnotacji

Nazwa Format Opis
nazwa_idx uleb128 nazwa elementu reprezentowana jako indeks w sekcji string_ids . Ciąg musi być zgodny ze składnią MemberName zdefiniowaną powyżej.
wartość zakodowana_wartość wartość elementu

Składnia ciągu

W pliku .dex istnieje kilka rodzajów elementów, które ostatecznie odnoszą się do ciągu znaków. Poniższe definicje w stylu BNF wskazują akceptowalną składnię tych ciągów.

Prosta nazwa

SimpleName jest podstawą składni nazw innych rzeczy. Format .dex zapewnia tutaj dużą swobodę (znacznie większą niż w przypadku większości popularnych języków źródłowych). W skrócie, prosta nazwa składa się z dowolnego znaku lub cyfry z niskiego ASCII, kilku określonych symboli z niskiego ASCII i większości punktów kodowych spoza ASCII, które nie są znakami kontrolnymi, spacjami ani znakami specjalnymi. Począwszy od wersji 040 format dodatkowo dopuszcza znaki spacji (kategoria Unicode Zs ). Należy zauważyć, że zastępcze punkty kodowe (w zakresie U+d800U+dfff ) nie są same w sobie uważane za prawidłowe znaki nazwy, ale prawidłowe dodatkowe znaki Unicode (które są reprezentowane przez ostateczną alternatywę reguły dla SimpleNameChar ) i powinny być reprezentowane w pliku jako pary zastępczych punktów kodowych w kodowaniu MUTF-8.

Prosta nazwa
SimpleNameChar ( SimpleNameChar )*
ProstaNazwaChar
'A''Z'
| 'a''z'
| '0''9'
| ' ' od wersji DEX 040
| '$'
| '-'
| '_'
| U+00a0 od wersji DEX 040
| U+00a1U+1fff
| U+2000U+200a od wersji DEX 040
| U+2010U+2027
| U+202f od wersji DEX 040
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

Nazwa członka

używane przez Field_id_item i method_id_item

MemberName to nazwa członka klasy, której członkami są pola, metody i klasy wewnętrzne.

Nazwa członka
Prosta nazwa
| '<' Prosta nazwa '>'

Pełna nazwa klasy

FullClassName to w pełni kwalifikowana nazwa klasy, zawierająca opcjonalny specyfikator pakietu, po którym następuje wymagana nazwa.

Pełna nazwa klasy
OpcjonalnyPrefiksPakietuProstaNazwa
OpcjonalnyPrefiksPakietu
( Prosta nazwa '/' )*

Deskryptor typu

Używany przez type_id_item

TypeDescriptor to reprezentacja dowolnego typu, w tym elementów pierwotnych, klas, tablic i void . Poniżej znajdziesz znaczenie różnych wersji.

TypDeskryptor
'V'
| Deskryptor typu pola
PoleTypeDescriptor
Deskryptor NonArrayFieldType
| ( '[' * 1…255) NonArrayFieldTypeDescriptor
NonArrayFieldTypeDescriptor
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L' Pełna nazwa klasy ';'

Krótki opis

Używany przez proto_id_item

ShortyDescriptor to krótka reprezentacja prototypu metody, obejmująca typy zwracane i parametry, z tą różnicą, że nie ma rozróżnienia między różnymi typami referencyjnymi (klasami lub tablicami). Zamiast tego wszystkie typy referencyjne są reprezentowane przez pojedynczy znak 'L' .

Krótki opis
Typ ShortyReturn ( Typ ShortyField )*
Typ ShortyReturn
'V'
| Typ ShortyField
Typ ShortyField
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'

Semantyka deskryptora typu

Takie jest znaczenie każdego z wariantów TypeDescriptor .

Składnia Oznaczający
V void ; ważne tylko dla typów zwracanych
Z boolean
B byte
S short
C char
I int
J long
F float
D double
L w pełni/kwalifikowany/Nazwa ; klasa fully.qualified.Name
[ deskryptor tablica descriptor , której można używać rekurencyjnie dla tablic tablic, chociaż posiadanie więcej niż 255 wymiarów jest nieprawidłowe.

Przedmioty i powiązane struktury

Ta sekcja zawiera definicje każdego elementu najwyższego poziomu, który może pojawić się w pliku .dex .

element nagłówka

Pojawia się w sekcji nagłówka

Wyrównanie: 4 bajty

Nazwa Format Opis
magia ubyte[8] = DEX_FILE_MAGIC wartość magiczna. Aby uzyskać więcej szczegółów, zobacz dyskusję powyżej w sekcji „ DEX_FILE_MAGIC ”.
suma kontrolna uint suma kontrolna adler32 reszty pliku (wszystko oprócz magic i tego pola); używany do wykrywania uszkodzeń plików
podpis ubajt[20] Sygnatura SHA-1 (hash) reszty pliku (wszystko oprócz magic , checksum i tego pola); używany do jednoznacznej identyfikacji plików
rozmiar pliku uint rozmiar całego pliku (łącznie z nagłówkiem) w bajtach
rozmiar_nagłówka uint = 0x70 rozmiar nagłówka (całej sekcji) w bajtach. Pozwala to na co najmniej ograniczoną kompatybilność wstecz/do przodu bez unieważniania formatu.
endian_tag uint = ENDIAN_CONSTANT znacznik endianizmu. Więcej szczegółów znajdziesz w dyskusji powyżej w sekcjach „ ENDIAN_CONSTANT i REVERSE_ENDIAN_CONSTANT ”.
rozmiar_linku uint rozmiar sekcji łącza lub 0 , jeśli ten plik nie jest połączony statycznie
link_wyłączony uint przesunięcie od początku pliku do sekcji łącza lub 0 , jeśli link_size == 0 . Przesunięcie, jeśli jest niezerowe, powinno być przesunięciem w sekcji link_data . W niniejszym dokumencie nie określono formatu wskazanych danych; to pole nagłówka (i poprzednie) pozostaje jako haczyki do wykorzystania w implementacjach wykonawczych.
mapa wyłączona uint przesunięcie od początku pliku do elementu mapy. Przesunięcie, które musi być niezerowe, powinno odpowiadać przesunięciu w sekcji data , a dane powinny być w formacie określonym przez „ map_list ” poniżej.
string_ids_size uint liczba ciągów na liście identyfikatorów ciągów
string_ids_off uint przesunięcie od początku pliku do listy identyfikatorów ciągów lub 0 , jeśli string_ids_size == 0 (co prawda dziwny przypadek Edge). Przesunięcie, jeśli jest niezerowe, powinno znajdować się na początku sekcji string_ids .
type_ids_size uint liczba elementów na liście identyfikatorów typów, maksymalnie 65535
type_ids_off uint przesunięcie od początku pliku do listy identyfikatorów typów lub 0 , jeśli type_ids_size == 0 (co prawda dziwny przypadek Edge). Przesunięcie, jeśli jest niezerowe, powinno znajdować się na początku sekcji type_ids .
proto_ids_size uint liczba elementów na liście identyfikatorów prototypów, maksymalnie 65535
proto_ids_off uint przesunięcie od początku pliku do listy identyfikatorów prototypów lub 0 , jeśli proto_ids_size == 0 (co prawda dziwny przypadek Edge). Przesunięcie, jeśli jest niezerowe, powinno znajdować się na początku sekcji proto_ids .
rozmiar_id_pola uint liczba elementów na liście identyfikatorów pól
pole_ids_off uint przesunięcie od początku pliku do listy identyfikatorów pól lub 0 , jeśli field_ids_size == 0 . Przesunięcie, jeśli jest niezerowe, powinno znajdować się na początku sekcji field_ids .
metoda_ids_rozmiar uint liczba elementów na liście identyfikatorów metod
method_ids_off uint przesunięcie od początku pliku do listy identyfikatorów metod lub 0 , jeśli method_ids_size == 0 . Przesunięcie, jeśli jest niezerowe, powinno znajdować się na początku sekcji method_ids .
class_defs_size uint liczba elementów na liście definicji klas
class_defs_off uint przesunięcie od początku pliku do listy definicji klas lub 0 , jeśli class_defs_size == 0 (co prawda dziwny przypadek Edge). Przesunięcie, jeśli jest niezerowe, powinno znajdować się na początku sekcji class_defs .
rozmiar_danych uint Rozmiar sekcji data w bajtach. Musi być parzystą wielokrotnością sizeof(uint).
dane_wył uint przesunięcie od początku pliku do początku sekcji data .

lista_map

Pojawia się w sekcji danych

Odniesienie do header_item

Wyrównanie: 4 bajty

To jest lista całej zawartości pliku, w kolejności. Zawiera pewną nadmiarowość w odniesieniu do header_item , ale ma być łatwą w użyciu formą iteracji po całym pliku. Dany typ musi pojawić się na mapie najwyżej raz, ale nie ma żadnych ograniczeń co do kolejności, w jakiej typy mogą się pojawiać, poza ograniczeniami wynikającymi z pozostałej części formatu (np. sekcja header musi pojawić się jako pierwsza, po której następuje string_ids sekcja itp.). Dodatkowo wpisy na mapie muszą być uporządkowane według przesunięcia początkowego i nie mogą na siebie zachodzić.

Nazwa Format Opis
rozmiar uint wielkość listy we wpisach
lista element_mapy[rozmiar] elementy listy

format elementu mapy

Nazwa Format Opis
typ skrócić rodzaj przedmiotów; Zobacz tabelę poniżej
nie używany skrócić (nie używany)
rozmiar uint liczba elementów, które można znaleźć we wskazanym przesunięciu
zrównoważyć uint przesunięcie od początku pliku do danych elementów

Wpisz kody

Typ przedmiotu Stały Wartość Rozmiar elementu w bajtach
element nagłówka TYPE_HEADER_ITEM 0x0000 0x70
string_id_item TYPE_STRING_ID_ITEM 0x0001 0x04
typ_id_item TYPE_TYPE_ID_ITEM 0x0002 0x04
proto_id_item TYPE_PROTO_ID_ITEM 0x0003 0x0c
element_id_pola TYPE_FIELD_ID_ITEM 0x0004 0x08
metoda_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
metoda_uchwytu_item TYPE_METHOD_HANDLE_ITEM 0x0008 0x08
lista_map TYPE_MAP_LIST 0x1000 4 + (rozmiar przedmiotu * 12)
lista_typów TYPE_TYPE_LIST 0x1001 4 + (rozmiar przedmiotu * 2)
lista_zestawów_adnotacji TYPE_ANNOTATION_SET_REF_LIST 0x1002 4 + (rozmiar przedmiotu * 4)
element_zestawu_adnotacji TYPE_ANNOTATION_SET_ITEM 0x1003 4 + (rozmiar przedmiotu * 4)
element_danych klasy TYPE_CLASS_DATA_ITEM 0x2000 domniemany; muszę przeanalizować
element_kodu TYPE_CODE_ITEM 0x2001 domniemany; muszę przeanalizować
element_danych_stringu TYPE_STRING_DATA_ITEM 0x2002 domniemany; muszę przeanalizować
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 domniemany; muszę przeanalizować
element_adnotacji TYPE_ANNOTATION_ITEM 0x2004 domniemany; muszę przeanalizować
zakodowany_element_tablicy TYPE_ENCODED_ARRAY_ITEM 0x2005 domniemany; muszę przeanalizować
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 domniemany; muszę przeanalizować
ukrytyapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 domniemany; muszę przeanalizować

string_id_item

Pojawia się w sekcji string_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
string_data_off uint przesunięcie od początku pliku do danych ciągu dla tego elementu. Przesunięcie powinno znajdować się w lokalizacji w sekcji data , a dane powinny być w formacie określonym przez „ string_data_item ” poniżej. Nie ma wymogu wyrównania dla przesunięcia.

element_danych_stringu

Pojawia się w sekcji danych

Wyrównanie: brak (wyrównanie bajtowe)

Nazwa Format Opis
utf16_rozmiar uleb128 rozmiar tego ciągu, w jednostkach kodu UTF-16 (co w wielu systemach jest „długością ciągu”). Oznacza to, że jest to zdekodowana długość ciągu. (Zakodowana długość jest implikowana przez położenie bajtu 0 )
dane ubajt[] seria jednostek kodu MUTF-8 (inaczej oktetów, czyli bajtów), po których następuje bajt o wartości 0 . Zobacz „Kodowanie MUTF-8 (zmodyfikowane UTF-8)” powyżej, aby uzyskać szczegółowe informacje i dyskusję na temat formatu danych.

Uwaga: Dopuszczalne jest posiadanie ciągu zawierającego (zakodowaną formę) jednostek kodu zastępczego UTF-16 (tj. U+d800U+dfff ) w izolacji lub poza kolejnością w stosunku do zwykłego kodowania Unicode na UTF-16. Jeśli to konieczne, odrzucenie takich nieprawidłowych kodowań należy do wyższego poziomu użycia ciągów.

typ_id_item

Pojawia się w sekcji type_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
deskryptor_idx uint indeks na listę string_ids dla ciągu deskryptora tego typu. Ciąg musi być zgodny ze składnią TypeDescriptor zdefiniowaną powyżej.

proto_id_item

Pojawia się w sekcji proto_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
krótki_idx uint indeks do listy string_ids dla krótkiego ciągu deskryptora tego prototypu. Ciąg musi być zgodny ze składnią ShortyDescriptor zdefiniowaną powyżej i musi odpowiadać typowi zwracanemu i parametrom tego elementu.
typ_powrotu_idx uint indeks na listę type_ids dla zwracanego typu tego prototypu
parametry_wyłączone uint przesunięcie od początku pliku do listy typów parametrów dla tego prototypu lub 0 , jeśli ten prototyp nie ma parametrów. To przesunięcie, jeśli jest niezerowe, powinno znajdować się w sekcji data , a dane tam powinny być w formacie określonym przez "type_list" poniżej. Dodatkowo na liście nie powinno być odniesienia do typu void .

element_id_pola

Pojawia się w sekcji Field_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
klasa_idx skrócić indeks do listy type_ids dla definiującego to pole. Musi to być typ klasy, a nie tablica lub typ pierwotny.
typ_idx skrócić indeks na listę type_ids dla typu tego pola
nazwa_idx uint wpisz nazwę tego pola na listę string_ids . Ciąg musi być zgodny ze składnią MemberName zdefiniowaną powyżej.

metoda_id_item

Pojawia się w sekcji method_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
klasa_idx skrócić indeks do listy type_ids dla definiującego tę metodę. Musi to być typ klasy lub tablicy, a nie typ pierwotny.
proto_idx skrócić indeksuj listę proto_ids dla prototypu tej metody
nazwa_idx uint wpisz nazwę tej metody na listę string_ids . Ciąg musi być zgodny ze składnią MemberName zdefiniowaną powyżej.

class_def_item

Pojawia się w sekcji class_defs

Wyrównanie: 4 bajty

Nazwa Format Opis
klasa_idx uint indeksuj do listy type_ids dla tej klasy. Musi to być typ klasy, a nie tablica lub typ pierwotny.
flagi dostępu uint flagi dostępu dla klasy ( public , final itp.). Aby uzyskać szczegółowe informacje, zobacz „Definicje access_flags ”.
superklasa_idx uint indeks do listy type_ids dla nadklasy lub stałą wartość NO_INDEX , jeśli ta klasa nie ma nadklasy (tj. jest klasą główną, taką jak Object ). Jeśli jest obecny, musi to być typ klasy, a nie tablica lub typ pierwotny.
interfejsy_wyłączone uint przesunięcie od początku pliku do listy interfejsów lub 0 , jeśli ich nie ma. To przesunięcie powinno znajdować się w sekcji data , a dane tam powinny być w formacie określonym przez „ type_list ” poniżej. Każdy element listy musi być typem klasy (a nie tablicą lub typem pierwotnym) i nie może zawierać żadnych duplikatów.
identyfikator_pliku_źródłowego uint indeks do listy string_ids dla nazwy pliku zawierającego oryginalne źródło (przynajmniej większości) tej klasy lub specjalną wartość NO_INDEX oznaczającą brak tej informacji. Element debug_info_item dowolnej metody może zastąpić ten plik źródłowy, ale oczekuje się, że większość klas będzie pochodzić tylko z jednego pliku źródłowego.
adnotacje_wyłączone uint przesunięcie od początku pliku do struktury adnotacji dla tej klasy lub 0 , jeśli nie ma żadnych adnotacji w tej klasie. To przesunięcie, jeśli jest niezerowe, powinno znajdować się w sekcji data , a dane tam powinny być w formacie określonym przez „ annotations_directory_item ” poniżej, przy czym wszystkie elementy odnoszą się do tej klasy jako definicji.
class_data_off uint przesunięcie od początku pliku do powiązanych danych klasy dla tego elementu lub 0 , jeśli nie ma danych klasy dla tej klasy. (Może tak być na przykład, jeśli ta klasa jest interfejsem znacznika.) Przesunięcie, jeśli jest niezerowe, powinno znajdować się w sekcji data , a dane tam powinny być w formacie określonym przez „ class_data_item ” poniżej, ze wszystkimi elementami odnoszącymi się do tej klasy jako definicji.
wartości_statyczne_wyłączone uint przesunięcie od początku pliku do listy wartości początkowych pól static lub 0 , jeśli ich nie ma (a wszystkie pola static mają być inicjalizowane wartością 0 lub null ). To przesunięcie powinno znajdować się w sekcji data , a dane tam powinny być w formacie określonym przez „ encoded_array_item ” poniżej. Rozmiar tablicy nie może być większy niż liczba pól static zadeklarowanych przez tę klasę, a elementy odpowiadają polom static w tej samej kolejności, jaką zadeklarowano w odpowiedniej field_list . Typ każdego elementu tablicy musi odpowiadać zadeklarowanemu typowi odpowiadającego mu pola. Jeśli w tablicy jest mniej elementów niż pól static , pozostałe pola są inicjowane odpowiednią dla typu wartością 0 lub null .

call_site_id_item

Pojawia się w sekcji call_site_ids

Wyrównanie: 4 bajty

Nazwa Format Opis
call_site_off uint przesunięcie od początku pliku, aby wywołać definicję witryny. Przesunięcie powinno znajdować się w sekcji danych, a dane w nim powinny być w formacie określonym przez „call_site_item” poniżej.

call_site_item

Pojawia się w sekcji danych

Wyrównanie: brak (wyrównanie bajtów)

Call_site_item to encoded_array_item, którego elementy odpowiadają argumentom dostarczonym do metody linkera ładującego. Pierwsze trzy argumenty to:

  1. Uchwyt metody reprezentujący metodę linkera ładowania początkowego (VALUE_METHOD_HANDLE).
  2. Nazwa metody, którą powinien rozwiązać linker ładowania początkowego (VALUE_STRING).
  3. Typ metody odpowiadający typowi nazwy metody, która ma zostać rozpoznana (VALUE_METHOD_TYPE).

Wszelkie dodatkowe argumenty są wartościami stałymi przekazywanymi do metody linkera ładującego. Argumenty te są przekazywane w kolejności i bez konwersji typów.

Uchwyt metody reprezentujący metodę linkera ładowania początkowego musi mieć typ zwracany java.lang.invoke.CallSite . Pierwsze trzy typy parametrów to:

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

Typy parametrów dodatkowych argumentów są określane na podstawie ich stałych wartości.

metoda_uchwytu_item

Pojawia się w sekcji method_handles

Wyrównanie: 4 bajty

Nazwa Format Opis
typ_uchwytu_metody Ushort rodzaj uchwytu metody; Zobacz tabelę poniżej
nie używany Ushort (nie używany)
field_or_method_id Ushort Pole lub identyfikator metody w zależności od tego, czy typ uchwytu metody jest akcesorium, czy inwidator metody
nie używany Ushort (nie używany)

Kody typu uchwytu metody

Stały Wartość Opis
Method_Handle_Type_static_put 0x00 Uchwyt metody to statyczny ustawinik pola (akcesorator)
Method_Handle_Type_static_get 0x01 Uchwyt metody to statyczne getter pola (Accessor)
Method_Handle_Type_Instance_put 0x02 Uchwyt metody to setter pola instancji (akcesorator)
Method_Handle_Type_Instance_get 0x03 Uchwyt metody to pola instancji Getter (Accessor)
Method_Handle_Type_invoke_static 0x04 Uchwyt metody to statyczny inwazja metody
Method_Handle_Type_invoke_instance 0x05 Uchwyt metody to instancja inwenter
Method_handle_type_invoke_constructor 0x06 Uchwyt metody jest inwenterem metody konstruktora
Method_Handle_Type_invoke_direct 0x07 Uchwyt metody jest bezpośrednim inwidowaniem metody
Method_Handle_Type_invoke_interface 0x08 Uchwyt metody to interfejs Method Invoker

class_data_item

Odwołane z klasy_def_item

Pojawia się w sekcji danych

Wyrównanie: Brak (bajtowy)

Nazwa Format Opis
static_fields_size ULEB128 liczba pól statycznych zdefiniowanych w tym elemencie
instance_fields_size ULEB128 liczba pól instancji zdefiniowanych w tym elemencie
Direct_Methods_Size ULEB128 liczba bezpośrednich metod zdefiniowanych w tym elemencie
Virtual_Methods_Size ULEB128 liczba wirtualnych metod zdefiniowanych w tym elemencie
Static_fields enkoded_field [static_fields_size] zdefiniowane pola statyczne, reprezentowane jako sekwencja zakodowanych elementów. Pola należy posortować według field_idx w rosnącej kolejności.
instance_fields enkoded_field [instance_fields_size] Zdefiniowane pola instancji, reprezentowane jako sekwencja zakodowanych elementów. Pola należy posortować według field_idx w rosnącej kolejności.
Direct_Methods enkoded_method [Direct_Methods_Size] Zdefiniowane metody bezpośrednie (dowolne metody static , private lub konstruktorowe) reprezentowane jako sekwencja zakodowanych elementów. Metody muszą być sortowane według method_idx w rosnącej kolejności.
Virtual_methods enkoded_method [virtual_methods_size] Zdefiniowane wirtualne (żadne z metod static , private lub konstruktorów), reprezentowane jako sekwencja zakodowanych elementów. Ta lista nie powinna zawierać odziedziczonych metod, chyba że klasa, którą reprezentuje ten element. Metody muszą być sortowane według method_idx w rosnącej kolejności. method_idx metody wirtualnej nie może być taka sama jak jakakolwiek metoda bezpośrednia.

Uwaga: Wszystkie instancje field_id i method_id muszą odnosić się do tej samej klasy definiującej.

Format kodeded_field

Nazwa Format Opis
field_idx_diff ULEB128 indeks na liście field_ids dla tożsamości tego pola (zawierają nazwę i deskryptor), reprezentowany jako różnica od indeksu poprzedniego elementu na liście. Indeks pierwszego elementu na liście jest reprezentowany bezpośrednio.
access_flags ULEB128 Dostęp do flag dla pola ( public , final itp.). Szczegółowe informacje znajdują się w „Definicje access_flags ”.

Format Encoded_Method

Nazwa Format Opis
Method_idx_diff ULEB128 indeks na liście method_ids dla tożsamości tej metody (zawierają nazwę i deskryptor), reprezentowaną jako różnica od indeksu poprzedniego elementu na liście. Indeks pierwszego elementu na liście jest reprezentowany bezpośrednio.
access_flags ULEB128 Dostęp do flag dla metody ( public , final itp.). Szczegółowe informacje znajdują się w „Definicje access_flags ”.
Code_off ULEB128 Offset od początku pliku do struktury kodu dla tej metody lub 0 , jeśli ta metoda jest abstract lub native . Przesunięcie powinno być w lokalizacji w sekcji data . Format danych jest określony przez „ code_item ” poniżej.

Type_List

Odwołane z klasy_def_item i proto_id_item

Pojawia się w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
rozmiar Uint rozmiar listy, we wpisach
lista type_item [rozmiar] elementy listy

Format typu_item

Nazwa Format Opis
type_idx Ushort indeks na liście type_ids

Code_item

Odwołany od Encoded_Method

Pojawia się w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
Registers_Size Ushort liczba rejestrów używanych przez ten kod
ins_Size Ushort liczba słów przychodzących argumentów do metody, dla której jest ten kod
outs_Size Ushort Liczba słów wychodzącego miejsca argumentów wymaganych przez niniejszy kod dla wywołania metody
Tries_Size Ushort Liczba try_item dla tego wystąpienia. Jeśli w tym przypadku pojawiają się one jako tablica tries tuż po insns .
debug_info_off Uint Offset od początku pliku do informacji o debugowaniu (numery linii + informacje o zmiennej lokalnej) dla tego kodu lub 0 , jeśli po prostu nie ma informacji. Przesunięcie, jeśli niezerowe, powinno być lokalizacja w sekcji data . Format danych jest określony przez „ debug_info_item ” poniżej.
INSNS_SIZE Uint rozmiar listy instrukcji, w 16-bitowych jednostkach kodowych
Insns Ushort [INSNS_SIZE] Rzeczywista tablica kodu bajtowego. Format kodu w tablicy insns jest określony przez dokument towarzyszący Dalvik Bytecode . Zauważ, że chociaż jest to zdefiniowane jako tablica ushort , istnieją pewne wewnętrzne struktury, które preferują wyrównanie czterech bajtów. Ponadto, jeśli zdarza się, że jest to w pliku zawiniętym przez endian, zamiana odbywa się tylko w poszczególnych instancjach ushort , a nie na większych strukturach wewnętrznych.
wyściółka ushort (opcjonalnie) = 0 Dwa bajty wyściółka, aby tries cztero-bajtowe są wyrównane. Ten element jest obecny tylko wtedy, gdy tries_size jest niezerowy, a insns_size jest dziwny.
Próbuje try_item [tries_size] (opcjonalnie) tablica wskazująca, gdzie w kodzie są złapane i jak je obsługiwać. Elementy tablicy muszą nie nakładać zasięgu i w kolejności od niskiego do wysokiego adresu. Ten element jest obecny tylko wtedy, gdy tries_size jest niezerowy.
Handlery enkoded_catch_handler_list (opcjonalnie) Bajty reprezentujące listę list typów połowów i powiązanych adresów obsługi. Każdy try_item ma przesunięcie bajtów do tej struktury. Ten element jest obecny tylko wtedy, gdy tries_size jest niezerowy.

Format try_item

Nazwa Format Opis
start_addr Uint Rozpoczęcie adres bloku kodu objęty tym wpisem. Adres jest liczbą 16-bitowych jednostek kodowych na początku pierwszej instrukcji zakrytej.
insn_count Ushort Liczba 16-bitowych jednostek kodowych objętych tym wpisem. Ostatnią jednostką kodu objęta (włączającą) to start_addr + insn_count - 1 .
Handler_off Ushort Offset w bajtach od początku powiązanego encoded_catch_hander_list do encoded_catch_handler dla tego wpisu. To musi być przesunięcie do początku encoded_catch_handler .

Encoded_catch_handler_list Format

Nazwa Format Opis
rozmiar ULEB128 rozmiar tej listy, we wpisach
lista encoded_catch_handler [Handlers_Size] Rzeczywista lista list obsługi, reprezentowana bezpośrednio (nie jako przesunięcia) i połączona sekwencyjnie

Format Encoded_Catch_Handler

Nazwa Format Opis
rozmiar SLAB128 Liczba typów połowów na tej liście. Jeśli nie dodatnie, to jest to negatywne liczba typów połowów, a po połowach następuje obsługa. Na przykład: size 0 oznacza, że ​​istnieje catch-all, ale nie ma wyraźnie wpisanych połowów. size 2 oznacza, że ​​istnieją dwa wyraźnie wpisane połowy i bez połowy. A size -1 oznacza, że ​​jest jeden wpisany połów wraz z catch -all.
Handlery enkoded_type_addr_pair [ABS (rozmiar)] Strumień elementów zakodowanych abs(size) , jeden dla każdego złapanego typu, w kolejności, że typy powinny być przetestowane.
catch_all_addr ULEB128 (opcjonalnie) Adres bajtowy modułu obsługi Catch-All. Ten element jest obecny tylko wtedy, gdy size nie jest pozytywny.

Format Encoded_Type_Addr_Pair

Nazwa Format Opis
type_idx ULEB128 indeks na liście type_ids dla typu wyjątku do złapania
adres ULEB128 Adres bajtowy powiązanego obsługi wyjątków

debug_info_item

Odwołane z Code_Item

Pojawia się w sekcji danych

Wyrównanie: Brak (bajtowy)

Każdy debug_info_item definiuje inspirowaną przez Dwarf3 maszynę stanową kodowaną przez bajtę, która po interpretacji emituje tabelę pozycji i (potencjalnie) informacje o zmiennej lokalnej dla code_item . Sekwencja rozpoczyna się od nagłówka o zmiennej długości (której długość zależy od liczby parametrów metody), następuje bajt maszyny stanu, a kończy bajtem DBG_END_SEQUENCE .

Maszyna stanowa składa się z pięciu rejestrów. Rejestr address reprezentuje przesunięcie instrukcji w powiązanym insns_item w 16-bitowych jednostkach kodowych. Rejestr address rozpoczyna się od 0 na początku każdej sekwencji debug_info i musi jedynie monotonicznie rosnąć. Rejestr line reprezentuje, jaki numer linii źródłowej powinien być powiązany z następnymi pozycjami wpisu tabeli emitowanej przez maszynę stanową. Jest inicjowany w nagłówku sekwencji i może zmieniać pozytywne lub negatywne kierunki, ale nigdy nie może być mniejsze niż 1 . Rejestr source_file reprezentuje plik źródłowy, do którego odnoszą się wpisy numeru linii. Jest inicjowany do wartości source_file_idx w class_def_item . Pozostałe dwie zmienne, prologue_end i epilogue_begin , to flagi boolowskie (zainicjowane do false ), które wskazują, czy kolejne emitowane pozycja należy uznać za metodę prolog lub epilog. Maszyna stanu musi również śledzić nazwę i rodzaj ostatniej zmiennej lokalnej na żywo w każdym rejestrze dla kodu DBG_RESTART_LOCAL .

Nagłówek jest następujący:

Nazwa Format Opis
line_start ULEB128 Wartość początkowa rejestru line maszyny stanowej. Nie reprezentuje faktycznego wpisu pozycji.
Parametry_Size ULEB128 liczba kodowanych nazw parametrów. Powinien istnieć jeden parametr metody, z wyłączeniem metody instancji, jeśli this .
Parameter_names ULEB128P1 [Parameters_size] Indeks ciągu nazwy parametru metody. Kodowana wartość NO_INDEX wskazuje, że żadna nazwa nie jest dostępna dla powiązanego parametru. Deskryptor typu i podpis są implikowane z deskryptora i podpisu metody.

Wartości kodu bajtów są następujące:

Nazwa Wartość Format Argumenty Opis
Dbg_end_ konsekwencja 0x00 (nic) kończy sekwencję informacyjną debugowania dla code_item
Dbg_advance_pc 0x01 ULEB128 addr_diff addr_diff : kwota do dodania do rejestracji adresu awansuje rejestr adresu bez emisji pozycji
Dbg_advance_line 0x02 SLAB128 line_diff line_diff : kwota do zmiany rejestru linii według awansuje rejestr linii bez emisji pozycji
Dbg_start_local 0x03 ULEB128 Register_num
ULEB128P1 name_idx
ULEB128P1 type_idx
register_num : rejestr, który będzie zawierał lokalne
name_idx : Indeks ciągu o nazwie
type_idx : indeks typu typu
wprowadza zmienną lokalną na bieżący adres. name_idx lub type_idx może być NO_INDEX , aby wskazać, że wartość ta jest nieznana.
Dbg_start_local_extended 0x04 ULEB128 Register_num
ULEB128P1 name_idx
ULEB128P1 type_idx
ULEB128P1 SIG_IDX
register_num : rejestr, który będzie zawierał lokalne
name_idx : Indeks ciągu o nazwie
type_idx : indeks typu typu
sig_idx : indeks ciągu podpisu typu
wprowadza lokalne z podpisem typu pod bieżącym adresem. Każdy z name_idx , type_idx lub sig_idx może być NO_INDEX , aby wskazać, że wartość ta jest nieznana. (Jeśli sig_idx jest -1 , te same dane można reprezentować bardziej wydajnie za pomocą Opcode DBG_START_LOCAL .)

Uwaga: Zobacz dyskusję pod „ dalvik.annotation.Signature ” poniżej, aby uzyskać zastrzeżenia dotyczące obsługi podpisów.

Dbg_end_local 0x05 ULEB128 Register_num register_num : rejestr zawierający lokalne oznacza aktualnie przeżywaną zmienną lokalną jako bezkształt na bieżącym adresie
DBG_RESTART_LOCAL 0x06 ULEB128 Register_num register_num : Zarejestruj się, aby ponownie uruchomić Ponownie wprowadza zmienną lokalną pod bieżącym adresem. Nazwa i typ są takie same jak ostatni lokalny, który był na żywo w określonym rejestrze.
Dbg_set_prologue_end 0x07 (nic) Ustawia rejestr maszyny stanu prologue_end , wskazując, że dodany wpis następnego pozycji powinien zostać uznany za koniec prologu metody (odpowiednie miejsce dla punktu przerwania metody). Rejestr prologue_end jest wyczyszczony przez dowolny specjalny ( >= 0x0a ).
Dbg_set_epilogue_begin 0x08 (nic) Ustawia rejestr maszyny stanu epilogue_begin , wskazując, że dodany wpis następnego pozycji powinien być uznany za początek epilogu metody (odpowiednie miejsce do zawieszenia wykonywania przed wyjściem metodą). Rejestr epilogue_begin jest wyczyszczony przez dowolny specjalny ( >= 0x0a ).
Dbg_set_file 0x09 ULEB128P1 name_idx name_idx : String Indeks nazwy pliku źródłowego; NO_INDEX jeśli nieznany Wskazuje, że wszystkie kolejne wpisy numeru linii odnoszą się do tej nazwy pliku źródłowego, zamiast domyślnej nazwy określonej w code_item
Specjalne opcody 0x0a… 0xff (nic) rozwija rejestry line i address , emituje pozycję i usuwa prologue_end i epilogue_begin . Opis patrz poniżej.

Specjalne opcody

Kody o wartości między 0x0a a 0xff (włączające) przesuwają zarówno rejestry line , jak i address o niewielką ilość, a następnie emitować nowy wpis tabeli pozycji. Wzór przyrostów jest następujący:

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

Odwołane z klasy_def_item

Pojawia się w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
class_annotations_off Uint Offset od początku pliku do adnotacji wykonanych bezpośrednio na klasie lub 0 , jeśli klasa nie ma bezpośrednich adnotacji. Przesunięcie, jeśli niezerowe, powinno być lokalizacja w sekcji data . Format danych jest określony przez „ annotation_set_item ” poniżej.
Fields_Size Uint liczba pól adnotowanych przez ten przedmiot
Annotated_Methods_Size Uint liczba metod opatrzonych przez ten przedmiot
Annotated_parameters_Size Uint Liczba parametrów metody wymienia adnotowane przez ten element
field_annotations field_annotation [fields_size] (opcjonalnie) Lista powiązanych adnotacji terenowych. Elementy listy należy posortować w rosnącej kolejności, według field_idx .
Method_annotations Method_annotation [Methods_Size] (opcjonalnie) Lista powiązanych adnotacji metod. Elementy listy muszą być sortowane w kolejności rosnącej, według method_idx .
Parameter_annotations parametr_annotation [parameters_size] (opcjonalnie) Lista powiązanych adnotacji parametrów metody. Elementy listy muszą być sortowane w kolejności rosnącej, według method_idx .

Uwaga: Wszystkie instancje field_id i method_id muszą odnosić się do tej samej klasy definiującej.

Format field_annotation

Nazwa Format Opis
field_idx Uint indeks na liście field_ids dla tożsamości pola adnotacji
Annotations_off Uint Offset od początku pliku do listy adnotacji dla pola. Przesunięcie powinno być w lokalizacji w sekcji data . Format danych jest określony przez „ annotation_set_item ” poniżej.

Method_annotation Format

Nazwa Format Opis
Method_idx Uint indeks na liście method_ids dla tożsamości metody adnotacji
Annotations_off Uint Offset od początku pliku do listy adnotacji dla metody. Przesunięcie powinno być w lokalizacji w sekcji data . Format danych jest określony przez „ annotation_set_item ” poniżej.

Parameter_annotation Format

Nazwa Format Opis
Method_idx Uint indeks do listy method_ids dla tożsamości metody, której parametry są adnotacjami
Annotations_off Uint Offset od początku pliku do listy adnotacji dla parametrów metody. Przesunięcie powinno być w lokalizacji w sekcji data . Format danych jest określony przez „ annotation_set_ref_list ” poniżej.

annotation_set_ref_list

Odwołany z parametru_annotations_item

Pojawia się w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
rozmiar Uint rozmiar listy, we wpisach
lista annotation_set_ref_item [rozmiar] elementy listy

Format adnotation_set_ref_item

Nazwa Format Opis
Annotations_off Uint Offset od początku pliku do odwołanego zestawu adnotacji lub 0 , jeśli nie ma adnotacji dla tego elementu. Przesunięcie, jeśli niezerowe, powinno być lokalizacja w sekcji data . Format danych jest określony przez „ annotation_set_item ” poniżej.

Annotation_Set_item

Odwołany od adnotations_directory_item, field_annotations_item, metod_annotations_item i adnotation_set_ref_item

Pojawia się w sekcji danych

Wyrównanie: 4 bajty

Nazwa Format Opis
rozmiar Uint rozmiar zestawu, we wpisach
wpisy Annotation_Off_Item [rozmiar] elementy zestawu. Elementy muszą być sortowane w kolejności rosnącej, według type_idx .

Format annotation_off_item

Nazwa Format Opis
Annotation_off Uint Offset od początku pliku do adnotacji. Przesunięcie powinno być do lokalizacji w sekcji data , a format danych w tej lokalizacji jest określony przez „ annotation_item ” poniżej.

Annotation_item

Odwołany od adnotation_set_item

Pojawia się w sekcji danych

Wyrównanie: Brak (bajtowy)

Nazwa Format Opis
widoczność Ubyte zamierzona widoczność tej adnotacji (patrz poniżej)
adnotacja koded_annotation Zakodowana zawartość adnotacji w formacie opisanym przez „Format encoded_annotation ” pod „ encoded_value Encoding” powyżej.

Wartości widoczności

Są to opcje pola visibility w annotation_item :

Nazwa Wartość Opis
Visibility_build 0x00 przeznaczone tylko do widocznego w czasie budowy (np. Podczas kompilacji innego kodu)
Visibility_runtime 0x01 przeznaczone do widocznego w czasie wykonywania
Visibility_system 0x02 przeznaczone do widocznego w czasie wykonywania, ale tylko do systemu podstawowego (a nie do zwykłego kodu użytkownika)

encoded_array_item

Odwołane z klasy_def_item

Pojawia się w sekcji danych

Wyrównanie: Brak (bajtowy)

Nazwa Format Opis
wartość enkoded_array bajty reprezentujące kodowaną wartość tablicy, w formacie określonym przez „ encoded_array Format” pod „ encoded_value Encoding” powyżej.

hiddenapi_class_data_item

W tej sekcji zawiera dane dotyczące ograniczonych interfejsów używanych przez każdą klasę.

Uwaga: Funkcja ukrytego API została wprowadzona w Android 10.0 i ma zastosowanie tylko do plików DEX klas na ścieżce klasy rozruchowej. Lista flag opisanych poniżej można rozszerzyć w przyszłych wydaniach Androida. Aby uzyskać więcej informacji, zobacz ograniczenia dotyczące interfejsów innych niż SDK .

Nazwa Format Opis
rozmiar Uint Całkowity rozmiar sekcji
przesunięcia uint [] tablica przesunięć indeksowanych przez class_idx . Wpis zero tablicy w indeksie class_idx oznacza, że ​​albo nie ma danych dla tej class_idx , albo wszystkie ukryte flagi API wynoszą zero. W przeciwnym razie wpis tablicy jest niezerowy i zawiera przesunięcie od początku sekcji do tablicy ukrytych flag API dla tej class_idx .
flagi ULEB128 [] Połączone tablice ukrytych flag API dla każdej klasy. Możliwe wartości flagi opisano w poniższej tabeli. Flagi są kodowane w tej samej kolejności, co pola i metody są kodowane w danych klasowych.

Rodzaje flag ograniczeń:

Nazwa Wartość Opis
Whitelist 0 Interfejsy, które mogą być swobodnie używane i są obsługiwane w ramach oficjalnie udokumentowanego indeksu pakietu Android Framework.
Greylist 1 Interfejsy inne niż SDK, które można używać niezależnie od docelowego poziomu API aplikacji.
czarna lista 2 Interfejsy inne niż SDK, których nie można użyć, niezależnie od docelowego poziomu API aplikacji. Dostęp do jednego z tych interfejsów powoduje błąd środowiska wykonawczego .
Greylist - Max - O. 3 Interfejsy inne niż SDK, które mogą być używane na Androida 8.x i poniżej, chyba że są ograniczone.
Greylist - Max - P. 4 Interfejsy inne niż SDK, które mogą być używane na Androida 9.x, chyba że są ograniczone.
GreyList - Max -Q 5 Interfejsy inne niż SDK, które mogą być używane na Androida 10.x, chyba że są ograniczone.
Greylist - Max - R. 6 Interfejsy inne niż SDK, które mogą być używane na Androida 11.x, chyba że są ograniczone.

Adnotacje systemowe

Adnotacje systemowe są wykorzystywane do przedstawienia różnych elementów refleksyjnych informacji o klasach (i metodach i polach). Informacje te są na ogół dostępne tylko pośrednio przez kod klienta (inne niż system).

Adnotacje systemowe są reprezentowane w plikach .dex jako adnotacje z widocznością ustawionymi na VISIBILITY_SYSTEM .

dalvik.annotation.annotationdefault

Pojawia się na metodach w interfejsach adnotacyjnych

Do każdego interfejsu adnotacji jest dołączona adnotacja AnnotationDefault , która chce wskazać domyślne powiązania.

Nazwa Format Opis
wartość Adnotacja Domyślne powiązania dla tej adnotacji, przedstawione jako adnotacja tego typu. Adnotacja nie musi zawierać wszystkich nazw zdefiniowanych przez adnotację; Brakujące nazwy po prostu nie mają wartości domyślnych.

dalvik.annotation.enclosingClass

Pojawia się na zajęciach

Do każdej klasy dołączona jest adnotacja EnclosingClass , która jest zdefiniowana jako członek innej klasy, per se, albo jest anonimowy, ale nie zdefiniowany w ciele metody (np. Syntetyczna klasa wewnętrzna). Każda klasa, która ma tę adnotację, musi również mieć adnotację InnerClass . Dodatkowo klasa nie może mieć zarówno EnclosingClass , jak i EnclosingMethod adnotacji.

Nazwa Format Opis
wartość Klasa klasa, która najlepiej leksykalnie obejmuje tę klasę

dalvik.annotation.enclosingMethod

Pojawia się na zajęciach

Do każdej klasy, która jest zdefiniowana w ciele metody, jest dołączona EnclosingMethod . Każda klasa, która ma tę adnotację, musi również mieć adnotację InnerClass . Dodatkowo klasa nie może mieć zarówno EnclosingClass , jak i EnclosingMethod adnotacji.

Nazwa Format Opis
wartość metoda Metoda, która najdalej leksykalnie obejmuje tę klasę

dalvik.annotation.innerclass

Pojawia się na zajęciach

Do każdej klasy dołączono adnotację InnerClass , która jest zdefiniowana w zakresie leksykalnej definicji innej klasy. Każda klasa, która ma tę adnotację, musi również zawierać adnotację EnclosingClass lub EnclosingMethod adnotację.

Nazwa Format Opis
nazwa Strunowy Pierwotnie zadeklarowana prosta nazwa tej klasy (nie uwzględniając żadnego przedrostka pakietu). Jeśli ta klasa jest anonimowa, nazwa jest null .
Accessflags wew Pierwotnie zadeklarowane flagi dostępu klasy (które mogą różnić się od efektywnych flag z powodu niedopasowania między modelami wykonania języka źródłowego a maszyną wirtualną docelową)

dalvik.annotation.memberclasses

Pojawia się na zajęciach

Do każdej klasy są dołączane do MemberClasses . (Klasa członkowska to bezpośrednia klasa wewnętrzna, która ma nazwę.)

Nazwa Format Opis
wartość Klasa[] tablica klas członków

dalvik.annotation.methodparameters

Pojawia się na metodach

Uwaga: Ta adnotacja została dodana po Androida 7.1. Jego obecność na wcześniejszych wydaniach z Androidem zostanie zignorowana.

Adnotacja MethodParameters jest opcjonalna i może być używana do dostarczania metadanych parametrów, takich jak nazwy parametrów i modyfikatory.

Adnotację można bezpiecznie pominąć w metodzie lub konstruktora, gdy metadane parametrów nie są wymagane w czasie wykonywania. java.lang.reflect.Parameter.isNamePresent() można użyć do sprawdzenia, czy metadane są obecne dla parametru, a powiązane metody odbicia, takie jak java.lang.reflect.Parameter.getName() , powrócą do domyślnego zachowania w czasie wykonywania. Jeśli informacje nie są obecne.

Przy uwzględnieniu metadanych parametrów kompilatory muszą zawierać informacje dla wygenerowanych klas, takich jak wyliczenia, ponieważ metadane parametrów zawiera to, czy parametr jest syntetyczny, czy nakazany.

Adnotacja MethodParameters opisuje tylko indywidualne parametry metody. Dlatego kompilatory mogą całkowicie pominąć adnotację dla konstruktorów i metod, które nie mają parametrów, ze względu na wydajność wielkości kodu i wykonania środowiska wykonawczego.

Tablice udokumentowane poniżej muszą mieć ten sam rozmiar, co w przypadku struktury DEX method_id_item powiązanej z metodą, w przeciwnym razie java.lang.reflect.MalformedParametersException zostanie wyrzucony w czasie wykonywania.

To znaczy: method_id_item.proto_idx -> proto_id_item.parameters_off -> type_list.size musi być taki sam jak names().length i accessFlags().length .

Ponieważ MethodParameters opisuje wszystkie parametry metody formalnej, nawet te, które nie są jawne lub domyślnie zadeklarowane w kodzie źródłowym, rozmiar tablic może różnić się od podpisu lub innych informacji o metadanych opartych wyłącznie na wyraźnych parametrach ogłoszonych w kodzie źródłowym. MethodParameters nie będą również zawierać żadnych informacji o parametrach odbiornika adnotacji typu, które nie istnieją w faktycznej metodzie.

Nazwa Format Opis
nazwy Strunowy[] Nazwy formalnych parametrów dla powiązanej metody. Tablica nie może być zerowa, ale musi być pusta, jeśli nie ma formalnych parametrów. Wartość w tablicy musi być null, jeśli parametr formalny z tym indeksem nie ma nazwy.
Jeśli ciągi nazwy parametrów są puste lub zawierają „.”, ';', '[' Lub '/', to java.lang.reflect.MalformedParametersException zostanie wyrzucony w czasie wykonywania.
Accessflags int [] Flagi dostępu formalnych parametrów dla powiązanej metody. Tablica nie może być zerowa, ale musi być pusta, jeśli nie ma formalnych parametrów.
Wartość to maska ​​nieco z następującymi wartościami:
  • 0x0010: Final, parametr został ogłoszony ostatecznym
  • 0x1000: syntetyczny parametr został wprowadzony przez kompilator
  • 0x8000: Mandrowane, parametr jest syntetyczny, ale także implikowany przez specyfikację języka
Jeśli jakieś bity zostaną ustawione poza tym zestawem, wówczas java.lang.reflect.MalformedParametersException zostanie wyrzucony w czasie wykonywania.

dalvik.annotation.signature

Pojawia się na zajęciach, polach i metodach

Do każdej klasy, pola lub metody jest dołączona do opisu Signature , która jest zdefiniowana w kategoriach bardziej skomplikowanego typu niż jest reprezentowana przez type_id_item . Format .dex nie definiuje formatu podpisów; Ma to jedynie na celu reprezentowanie wszelkich podpisów, jakie wymaga języka źródłowego, aby pomyślnie wdrożyć semantykę tego języka. W związku z tym podpisy nie są na ogół analizowane (lub weryfikowane) przez implementacje maszyn wirtualnych. Podpisy są po prostu przekazywane interfejsom API i narzędzi wyższego poziomu (takich jak debuggery). Dlatego wszelkie użycie podpisu powinno być napisane, aby nie przyjmować żadnych założeń dotyczących tylko otrzymywania ważnych podpisów, wyraźnie strzegącym się przed możliwością spotkania się z syntaktycznie nieważnym podpisem.

Ponieważ sznurki podpisowe mają tendencję do wielu zduplikowanych treści, Signature adnotacja jest zdefiniowana jako tablica ciągów, w których powielone elementy naturalnie odnoszą się do tych samych danych podstawowych, a podpis jest podejmowany jako połączenie wszystkich ciągów w tablicy . Nie ma żadnych zasad dotyczących rozdzielenia podpisu w oddzielne struny; To zależy całkowicie do narzędzi generujących pliki .dex .

Nazwa Format Opis
wartość Strunowy[] podpis tej klasy lub członka, jako szereg strun, które mają być połączone razem

dalvik.annotation.throws

Pojawia się na metodach

Do każdej Throws , która jest zadeklarowana do rzucania jednego lub więcej typów wyjątków.

Nazwa Format Opis
wartość Klasa[] Rzut Rzuty