Einschränkungen

Eine .dex Datei ist das Transportformat für Dalvik-Bytecode. Es gibt bestimmte syntaktische und semantische Einschränkungen dafür, dass eine Datei eine gültige .dex Datei ist, und eine Laufzeit ist erforderlich, um nur gültige .dex-Dateien zu unterstützen.

Allgemeine Einschränkungen der .dex-Integrität

Allgemeine Integritätseinschränkungen betreffen die größere Struktur einer .dex Datei, wie im Detail im .dex -Format beschrieben.

Kennung Beschreibung
G1 Die magic Nummer der .dex Datei muss dex\n035\0 oder dex\n037\0 sein.
G2 Die Prüfsumme muss eine Adler-32-Prüfsumme des gesamten Dateiinhalts sein, mit Ausnahme magic und checksum .
G3 Die Signatur muss ein SHA-1-Hash des gesamten Dateiinhalts sein, mit Ausnahme magic , checksum und signature .
G4 Die file_size muss mit der tatsächlichen Dateigröße in Bytes übereinstimmen.
G5 Die header_size muss den Wert haben: 0x70
G6 Das endian_tag muss entweder den Wert ENDIAN_CONSTANT oder REVERSE_ENDIAN_CONSTANT haben
G7 Für jeden der link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs und data müssen die Felder offset und size entweder beide Null oder beide ungleich Null sein. Im letzteren Fall muss der Offset auf vier Bytes ausgerichtet sein.
G8 Alle Offset-Felder im Header außer map_off müssen auf vier Bytes ausgerichtet sein.
G9 Das Feld map_off muss entweder Null sein oder auf den Datenabschnitt zeigen. Im letzteren Fall muss der data vorhanden sein.
G10 Keiner der link , string_ids , type_ids , proto_ids , field_ids , method_ids , class_defs und data darf einander oder den Header überlappen.
G11 Wenn eine Karte vorhanden ist, muss jeder Karteneintrag einen gültigen Typ haben. Jeder Typ darf höchstens einmal vorkommen.
G12 Wenn eine Karte vorhanden ist, muss jeder Karteneintrag einen Offset und eine Größe ungleich Null haben. Der Offset muss auf den entsprechenden Abschnitt der Datei zeigen (dh ein string_id_item muss auf den Abschnitt string_ids zeigen) und die explizite oder implizite Größe des Elements muss mit dem tatsächlichen Inhalt und der Größe des Abschnitts übereinstimmen.
G13 Wenn eine Karte vorhanden ist, muss der Offset des Karteneintrags n+1 größer oder gleich dem Offset des Karteneintrags n plus than size of map entry n sein. Dies impliziert nicht überlappende Einträge und eine Reihenfolge von unten nach oben.
G14 Die folgenden Eintragstypen müssen einen Offset haben, der auf vier Bytes ausgerichtet ist: 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 Für jedes string_id_item muss das Feld string_data_off einen gültigen Verweis auf den data enthalten. Für das referenzierte string_data_item muss das data eine gültige MUTF-8-Zeichenfolge enthalten und die utf16_size muss mit der dekodierten Länge der Zeichenfolge übereinstimmen.
G16 Für jedes type_id_item muss das Feld descriptor_idx einen gültigen Verweis auf die string_ids Liste enthalten. Die referenzierte Zeichenfolge muss ein gültiger Typdeskriptor sein.
G17 Für jedes proto_id_item muss das Feld shorty_idx einen gültigen Verweis auf die string_ids Liste enthalten. Die referenzierte Zeichenfolge muss ein gültiger Shorty-Deskriptor sein. Außerdem muss das Feld return_type_idx ein gültiger Index in den Abschnitt „ type_ids sein und das Feld parameters_off muss entweder Null oder ein gültiger Offset sein, der in den Abschnitt data zeigt. Bei einem Wert ungleich Null darf die Parameterliste keine ungültigen Einträge enthalten.
G18 Für jedes field_id_item müssen sowohl das class_idx als auch type_idx Feld gültige Indizes in der type_ids Liste sein. Der von class_idx referenzierte Eintrag muss ein Nicht-Array-Referenztyp sein. Darüber hinaus muss das Feld name_idx ein gültiger Verweis auf den Abschnitt „ string_ids sein und der Inhalt des referenzierten Eintrags muss der MemberName Spezifikation entsprechen.
G19 Für jedes method_id_item muss das Feld class_idx ein gültiger Index im Abschnitt type_ids sein und der referenzierte Eintrag muss ein Nicht-Array-Referenztyp sein. Das Feld proto_id muss eine gültige Referenz in der proto_ids Liste sein. Das Feld name_idx muss ein gültiger Verweis auf den Abschnitt string_ids sein und der Inhalt des referenzierten Eintrags muss der MemberName Spezifikation entsprechen.
G20 Für jedes field_id_item muss das Feld class_idx ein gültiger Index in der Liste type_ids sein. Der referenzierte Eintrag muss ein Nicht-Array-Referenztyp sein.

Statische Bytecode-Einschränkungen

Statische Einschränkungen sind Einschränkungen für einzelne Elemente des Bytecodes. Sie können in der Regel ohne den Einsatz von Kontroll- oder Datenflussanalysetechniken überprüft werden.

Kennung Beschreibung
A1 Das insns Array darf nicht leer sein.
A2 Der erste Opcode im insns -Array muss den Index Null haben.
A3 Das insns Array darf nur gültige Dalvik-Opcodes enthalten.
A4 Der Index der Anweisung n+1 muss unter Berücksichtigung möglicher Operanden gleich dem Index der Anweisung n plus der Länge der Anweisung n sein.
A5 Die letzte Anweisung im insns Array muss am Index insns_size-1 enden.
A6 Alle goto und if-<kind> -Ziele müssen Opcodes innerhalb derselben Methode sein.
A7 Alle Ziele einer packed-switch Anweisung müssen Opcodes innerhalb derselben Methode sein. Die Größe und die Liste der Ziele müssen konsistent sein.
A8 Alle Ziele einer sparse-switch Anweisung müssen Opcodes innerhalb derselben Methode sein. Die entsprechende Tabelle muss konsistent und von unten nach oben sortiert sein.
A9 Der B Operand der Anweisungen const-string und const-string/jumbo muss ein gültiger Index im String-Konstantenpool sein.
A10 Der C Operand der Anweisungen iget<kind> und iput<kind> muss ein gültiger Index im Feldkonstantenpool sein. Der referenzierte Eintrag muss ein Instanzfeld darstellen.
A11 Der C Operand der Anweisungen sget<kind> und sput<kind> muss ein gültiger Index im Feldkonstantenpool sein. Der referenzierte Eintrag muss ein statisches Feld darstellen.
A12 Der C Operand der Anweisungen invoke-virtual , invoke-super , invoke-direct und invoke-static muss ein gültiger Index im Methodenkonstantenpool sein.
A13 Der B Operand der Anweisungen invoke-virtual/range , invoke-super/range , invoke-direct/range und invoke-static/range muss ein gültiger Index im Methodenkonstantenpool sein.
A14 Eine Methode, deren Name mit „<“ beginnt, darf nur implizit von der VM aufgerufen werden, nicht von Code, der aus einer .dex Datei stammt. Die einzige Ausnahme ist der Instanzinitialisierer, der durch invoke-direct aufgerufen werden kann.
A15 Der C Operand der invoke-interface Anweisung muss ein gültiger Index im Methodenkonstantenpool sein. Die referenzierte method_id muss zu einer Schnittstelle (nicht zu einer Klasse) gehören.
A16 Der B Operand der invoke-interface/range Anweisung muss ein gültiger Index im Methodenkonstantenpool sein. Die referenzierte method_id muss zu einer Schnittstelle (nicht zu einer Klasse) gehören.
A17 Der B Operand der Anweisungen const-class , check-cast , new-instance und filled-new-array/range muss ein gültiger Index im Typkonstantenpool sein.
A18 Der C Operand der Anweisungen instance-of , new-array “ und filled-new-array muss ein gültiger Index im Typkonstantenpool sein.
A19 Die Abmessungen eines Arrays, das durch eine new-array Anweisung erstellt wurde, müssen kleiner als 256 sein.
A20 Die new Anweisung darf sich nicht auf Array-Klassen, Schnittstellen oder abstrakte Klassen beziehen.
A21 Der Typ, auf den sich eine new-array Anweisung bezieht, muss ein gültiger Nicht-Referenztyp sein.
A22 Alle Register, auf die ein Befehl mit einfacher Breite (nicht paarweise) verweist, müssen für die aktuelle Methode gültig sein. Das heißt, ihre Indizes dürfen nicht negativ und kleiner als registers_size sein.
A23 Alle Register, auf die ein Befehl in doppelter Breite (Paar) verweist, müssen für die aktuelle Methode gültig sein. Das heißt, ihre Indizes dürfen nicht negativ und kleiner als registers_size-1 sein.
A24 Der Operand method_id der Anweisungen invoke-virtual und invoke-direct muss zu einer Klasse (nicht zu einer Schnittstelle) gehören. In Dex-Dateien vor Version 037 muss das Gleiche auch für die Anweisungen invoke-super und invoke-static gelten.
A25 Der Operand method_id der Anweisungen invoke-virtual/range und invoke-direct/range muss zu einer Klasse (nicht zu einer Schnittstelle) gehören. In Dex-Dateien vor Version 037 muss das Gleiche auch für die Anweisungen invoke-super/range und invoke-static/range gelten.

Strukturelle Bytecode-Einschränkungen

Strukturelle Einschränkungen sind Einschränkungen für Beziehungen zwischen mehreren Elementen des Bytecodes. Sie können normalerweise nicht ohne den Einsatz von Kontroll- oder Datenflussanalysetechniken überprüft werden.

Kennung Beschreibung
B1 Anzahl und Art der Argumente (Register und unmittelbare Werte) müssen immer mit der Anweisung übereinstimmen.
B2 Registerpaare dürfen niemals aufgelöst werden.
B3 Ein Register (oder Paar) muss zuerst zugewiesen werden, bevor es gelesen werden kann.
B4 Eine invoke-direct Anweisung darf einen Instanzinitialisierer oder eine Methode nur in der aktuellen Klasse oder einer ihrer Superklassen aufrufen.
B5 Ein Instanzinitialisierer darf nur für eine nicht initialisierte Instanz aufgerufen werden.
B6 Instanzmethoden dürfen nur auf bereits initialisierten Instanzen aufgerufen werden und auf Instanzfelder kann nur auf bereits initialisierte Instanzen zugegriffen werden.
B7 Ein Register, das das Ergebnis eines Befehls für eine new-instance enthält, darf nicht verwendet werden, wenn derselbe Befehl new-instance erneut ausgeführt wird, bevor die Instanz initialisiert wird.
B8 Ein Instanzinitialisierer muss einen anderen Instanzinitialisierer (gleiche Klasse oder Oberklasse) aufrufen, bevor auf Instanzmitglieder zugegriffen werden kann. Ausnahmen bilden nicht geerbte Instanzfelder, die vor dem Aufruf eines anderen Initialisierers zugewiesen werden können, und die Object Klasse im Allgemeinen.
B9 Alle tatsächlichen Methodenargumente müssen mit ihren jeweiligen formalen Argumenten zuweisungskompatibel sein.
B10 Für jeden Instanzmethodenaufruf muss die tatsächliche Instanz mit der in der Anweisung angegebenen Klasse oder Schnittstelle zuweisungskompatibel sein.
B11 Eine return<kind> -Anweisung muss mit dem Rückgabetyp ihrer Methode übereinstimmen.
B12 Beim Zugriff auf geschützte Mitglieder einer Superklasse muss der tatsächliche Typ der Instanz, auf die zugegriffen wird, entweder die aktuelle Klasse oder eine ihrer Unterklassen sein.
B13 Der Typ eines in einem statischen Feld gespeicherten Werts muss mit dem Feldtyp zuweisungskompatibel oder in diesen konvertierbar sein.
B14 Der Typ eines in einem Feld gespeicherten Werts muss mit dem Feldtyp zuweisungskompatibel oder in diesen konvertierbar sein.
B15 Der Typ jedes in einem Array gespeicherten Werts muss mit dem Komponententyp des Arrays zuweisungskompatibel sein.
B16 Der A Operand einer throw Anweisung muss mit java.lang.Throwable zuweisungskompatibel sein.
B17 Die letzte erreichbare Anweisung einer Methode muss entweder eine Rückwärts goto oder Branch-Anweisung, eine return -Anweisung oder eine throw -Anweisung sein. Es darf nicht möglich sein, das insns Array unten zu belassen.
B18 Die nicht zugewiesene Hälfte eines früheren Registerpaars kann möglicherweise nicht gelesen werden (wird als ungültig betrachtet), bis sie durch einen anderen Befehl neu zugewiesen wurde.
B19 Einer move-result<kind> -Anweisung muss (im insns -Array) unmittelbar eine invoke-<kind> -Anweisung vorangehen. Die einzige Ausnahme ist die Anweisung move-result-object , der auch eine Anweisung filled-new-array vorangestellt sein kann.
B20 Einer move-result<kind> -Anweisung muss (im tatsächlichen Kontrollfluss) unmittelbar eine passende return-<kind> -Anweisung vorangehen (zu dieser darf nicht gesprungen werden). Die einzige Ausnahme ist die Anweisung move-result-object , der auch eine Anweisung filled-new-array vorangestellt sein kann.
B21 Eine move-exception Anweisung darf nur als erste Anweisung in einem Ausnahmehandler erscheinen.
B22 Die Pseudoanweisungen packed-switch-data , sparse-switch-data und fill-array-data dürfen für den Kontrollfluss nicht erreichbar sein.