Format exécutable Dalvik

Ce document décrit la mise en page et le contenu des fichiers .dex, qui sont utilisés pour contenir un ensemble de définitions de classe et les données complémentaires associées.

Guide des types

Nom Description
octet Entier signé 8 bits
ubyte Entier non signé 8 bits
court Entier signé 16 bits, little-endian
ushort Entier non signé 16 bits, little-endian
int Entier signé 32 bits, little-endian
uint Entier non signé 32 bits, little-endian
long Entier signé de 64 bits, little-endian
ulong Entier non signé de 64 bits, little-endian
sleb128 LEB128 signé, longueur variable (voir ci-dessous)
uleb128 LEB128 non signé, longueur variable (voir ci-dessous)
uleb128p1 LEB128 non signé plus 1, longueur variable (voir ci-dessous)

LEB128

LEB128 ("Little-Endian Base 128") est un codage à longueur variable pour des quantités d'entiers signés ou non signés arbitraires. Le format a été emprunté à la spécification DWARF3. Dans un fichier .dex, LEB128 n'est utilisé que pour encoder des quantités de 32 bits.

Chaque valeur encodée LEB128 se compose d'un à cinq octets, qui représentent ensemble une seule valeur de 32 bits. Le bit le plus significatif de chaque octet est défini, à l'exception du dernier octet de la séquence, dont le bit le plus significatif est effacé. Les sept bits restants de chaque octet correspondent à la charge utile, avec les sept bits les moins significatifs de la quantité dans le premier octet, les sept suivants dans le deuxième octet, et ainsi de suite. Dans le cas d'un LEB128 signé (sleb128), le bit de charge utile le plus significatif de l'octet final de la séquence est étendu pour produire la valeur finale. Dans le cas non signé (uleb128), tous les bits non représentés explicitement sont interprétés comme 0.

Diagramme par bits d'une valeur LEB128 de deux octets
Premier octet Deuxième octet
1 bit6 bit5 bit4 bit3 bit 2 bit1 bit0 0 bit13 bit12 bit11 bit10 bit9 bit8 bit7

La variante uleb128p1 est utilisée pour représenter une valeur signée, où la représentation est de la valeur plus un encodée en tant que uleb128. Cela fait de l'encodage de -1 (ou de la valeur non signée 0xffffffff) un seul octet, mais pas d'autre nombre négatif. Cette fonctionnalité est utile dans les cas exacts où le nombre représenté doit être non négatif ou -1 (ou 0xffffffff), et où aucune autre valeur négative n'est autorisée (ou où de grandes valeurs non signées ne sont probablement pas nécessaires).

Voici quelques exemples de formats:

Séquence encodée En tant que sleb128 En tant que uleb128 En tant que uleb128p1
0000-1
01110
7f-1127126
80 7f-1281625616255

Mise en page du fichier

Nom Format Description
en-tête header_item l'en-tête
string_ids string_id_item[] liste des identifiants de chaîne. Il s'agit d'identifiants pour toutes les chaînes utilisées par ce fichier, soit pour la dénomination interne (par exemple, les descripteurs de type), soit en tant qu'objets constants référencés par le code. Cette liste doit être triée par contenu de la chaîne, à l'aide de valeurs de points de code UTF-16 (et non de manière sensible à la langue), et ne doit pas contenir d'entrées en double.
type_ids type_id_item[] Liste des identifiants de type. Il s'agit d'identifiants pour tous les types (classes, tableaux ou types primitifs) auxquels ce fichier fait référence, qu'ils soient définis dans le fichier ou non. Cette liste doit être triée par indice string_id et ne doit pas contenir d'entrées en double.
proto_ids proto_id_item[] Liste des identifiants de prototype de méthode. Il s'agit des identifiants de tous les prototypes référencés par ce fichier. Cette liste doit être triée par ordre majeur de type de retour (par indice type_id), puis par liste d'arguments (ordre lexicographique, arguments individuels triés par indice type_id). La liste ne doit pas contenir d'entrées en double.
field_ids field_id_item[] Liste des identifiants de champ. Il s'agit d'identifiants pour tous les champs auxquels ce fichier fait référence, qu'ils soient définis dans le fichier ou non. Cette liste doit être triée, où le type de définition (par indice type_id) est l'ordre principal, le nom du champ (par indice string_id) est l'ordre intermédiaire et le type (par indice type_id) est l'ordre mineur. La liste ne doit pas contenir d'entrées en double.
method_ids method_id_item[] Liste des identifiants de méthode. Il s'agit d'identifiants pour toutes les méthodes auxquelles ce fichier fait référence, qu'elles soient définies dans le fichier ou non. Cette liste doit être triée, où le type de définition (par indice type_id) est l'ordre principal, le nom de la méthode (par indice string_id) est l'ordre intermédiaire et le prototype de la méthode (par indice proto_id) est l'ordre mineur. La liste ne doit pas contenir d'entrées en double.
class_defs class_def_item[] liste des définitions de classe. Les classes doivent être triées de sorte que la superclasse et les interfaces implémentées d'une classe donnée apparaissent dans la liste avant la classe référente. De plus, il est invalide qu'une définition d'une classe du même nom apparaisse plusieurs fois dans la liste.
call_site_ids call_site_id_item[] liste des identifiants de site d'appel. Il s'agit d'identifiants pour tous les sites d'appel auxquels ce fichier fait référence, qu'ils soient définis dans le fichier ou non. Cette liste doit être triée par ordre croissant de call_site_off.
method_handles method_handle_item[] Liste des handles de méthode. Liste de tous les gestionnaires de méthode référencés par ce fichier, qu'ils soient définis dans le fichier ou non. Cette liste n'est pas triée et peut contenir des doublons qui correspondent logiquement à différentes instances de poignée de méthode.
de données ubyte[] zone de données contenant toutes les données d'assistance pour les tables listées ci-dessus. Les différents éléments ont des exigences d'alignement différentes, et des octets de remplissage sont insérés avant chaque élément si nécessaire pour obtenir un alignement correct.
link_data ubyte[] données utilisées dans les fichiers liés de manière statique. Le format des données de cette section n'est pas spécifié dans ce document. Cette section est vide dans les fichiers non associés, et les implémentations d'environnement d'exécution peuvent l'utiliser à leur guise.

Format du conteneur

La version 41 introduit un nouveau format de conteneur pour les données DEX dans le but d'économiser de l'espace. Ce format de conteneur permet de combiner plusieurs fichiers DEX logiques en un seul fichier physique. Le nouveau format est essentiellement une concatenaison naïve de fichiers au format précédent, avec quelques différences:

  • file_size correspond à la taille du fichier logique, et non du fichier physique. Il peut être utilisé pour itérer sur tous les fichiers logiques du conteneur.
  • Les fichiers dex logiques peuvent faire référence à toutes les données ultérieures du conteneur (mais pas à celles antérieures). Cela permet aux fichiers dex de partager des données, telles que des chaînes, entre eux.
  • Tous les décalages sont relatifs au fichier physique. Aucun décalage n'est relatif à l'en-tête. Cela garantit que les sections avec des décalages peuvent être partagées entre les fichiers logiques.
  • L'en-tête ajoute deux nouveaux champs pour décrire les limites du conteneur. Il s'agit d'une vérification de cohérence supplémentaire qui facilite le portage du code vers le nouveau format.
  • Les champs data_size et data_off ne sont plus utilisés. Les données peuvent être réparties sur plusieurs fichiers logiques et ne doivent pas être contiguës.

Définitions de champ de bits, de chaîne et de constante

DEX_FILE_MAGIC

Intégré à header_item

Le tableau/chaîne constant DEX_FILE_MAGIC est la liste d'octets qui doit apparaître au début d'un fichier .dex pour qu'il soit reconnu comme tel. La valeur contient intentionnellement une nouvelle ligne ("\n" ou 0x0a) et un octet nul ("\0" ou 0x00) afin de faciliter la détection de certaines formes de corruption. La valeur encode également un numéro de version de format sous la forme de trois chiffres décimaux, qui devrait augmenter de manière monotone au fil du temps à mesure que le format évolue.

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

Remarque:La prise en charge de la version 040 du format a été ajoutée dans la version Android 10.0, ce qui a étendu l'ensemble des caractères autorisés dans SimpleNames.

Remarque:La prise en charge de la version 039 du format a été ajoutée dans la version Android 9.0, qui a introduit deux nouveaux bytecodes, const-method-handle et const-method-type. (Chacun d'eux est décrit dans le tableau Récapitulatif de l'ensemble de bytecode.) Dans Android 10, la version 039 étend le format de fichier DEX pour inclure des informations d'API masquées qui ne s'appliquent qu'aux fichiers DEX sur le chemin de classe de démarrage.

Remarque:La prise en charge de la version 038 du format a été ajoutée dans la version 8.0 d'Android. La version 038 a ajouté de nouveaux bytecodes (invoke-polymorphic et invoke-custom) et des données pour les poignées de méthode.

Remarque:La prise en charge de la version 037 du format a été ajoutée dans la version Android 7.0. Avant la version 037, la plupart des versions d'Android utilisaient la version 035 du format. La seule différence entre les versions 035 et 037 est l'ajout de méthodes par défaut et l'ajustement de invoke.

Remarque:Au moins deux versions antérieures du format ont été utilisées dans des versions logicielles publiques largement disponibles. Par exemple, la version 009 a été utilisée pour les versions M3 de la plate-forme Android (novembre-décembre 2007), et la version 013 pour les versions M5 de la plate-forme Android (février-mars 2008). À plusieurs égards, ces versions antérieures du format diffèrent considérablement de la version décrite dans ce document.

ENDIAN_CONSTANT et REVERSE_ENDIAN_CONSTANT

Intégré à header_item

La constante ENDIAN_CONSTANT permet d'indiquer l'endianité du fichier dans lequel elle se trouve. Bien que le format .dex standard soit en ordre octets peu-endian, les implémentations peuvent choisir d'effectuer un échange d'octets. Si une implémentation rencontre un en-tête dont le endian_tag est REVERSE_ENDIAN_CONSTANT au lieu de ENDIAN_CONSTANT, elle sait que le fichier a été permuté par octet à partir de la forme attendue.

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

NO_INDEX

Intégrés à class_def_item et debug_info_item

La constante NO_INDEX permet d'indiquer qu'une valeur d'index est absente.

Remarque:Cette valeur n'est pas définie sur 0, car il s'agit généralement d'un indice valide.

La valeur choisie pour NO_INDEX peut être représentée par un seul octet dans l'encodage uleb128p1.

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

Définitions des access_flags

Intégré dans class_def_item, encoded_field, encoded_method et InnerClass

Les champs de bits de ces indicateurs sont utilisés pour indiquer l'accessibilité et les propriétés globales des classes et des membres de classe.

Nom Valeur Pour les classes (et les annotations InnerClass) Pour les champs Pour les méthodes
ACC_PUBLIC 0x1 public: visible partout public: visible partout public: visible partout
ACC_PRIVATE 0x2 * private: visible uniquement par la classe de définition private: visible uniquement par la classe de définition private: visible uniquement par la classe de définition
ACC_PROTECTED 0x4 * protected: visible pour le package et les sous-classes protected: visible pour le package et les sous-classes protected: visible pour le package et les sous-classes
ACC_STATIC 0x8 * static: n'est pas construit avec une référence this externe static: global pour la classe de définition static: n'accepte pas d'argument this
ACC_FINAL 0x10 final: non sous-classable final: immuable après la construction final: non remplaçable
ACC_SYNCHRONIZED 0x20     synchronized: verrouillage associé acquis automatiquement autour de l'appel de cette méthode.

Remarque:Cette valeur ne peut être définie que lorsque ACC_NATIVE est également défini.

ACC_VOLATILE 0x40   volatile: règles d'accès spéciales pour améliorer la sécurité des threads  
ACC_BRIDGE 0x40     méthode de pont, ajoutée automatiquement par le compilateur en tant que pont sécurisé
ACC_TRANSIENT 0x80   transient: ne pas être enregistré par la sérialisation par défaut  
ACC_VARARGS 0x80     Le dernier argument doit être traité comme un argument "rest" par le compilateur
ACC_NATIVE 0x100     native: implémenté en code natif
ACC_INTERFACE 0x200 interface: classe abstraite multi-implémentable    
ACC_ABSTRACT 0x400 abstract: non instanciable directement   abstract: non implémenté par cette classe
ACC_STRICT 0x800     strictfp: règles strictes pour l'arithmétique à virgule flottante
ACC_SYNTHETIC 0x1000 ne sont pas définies directement dans le code source ; ne sont pas définies directement dans le code source ; ne sont pas définies directement dans le code source ;
ACC_ANNOTATION 0x2000 déclarée comme une classe d'annotation    
ACC_ENUM 0x4000 déclaré comme un type énuméré déclarée en tant que valeur énumérée  
(inutilisé) 0x8000      
ACC_CONSTRUCTOR 0x10000     méthode constructeur (initialiseur de classe ou d'instance)
ACC_DECLARED_
SYNCHRONIZED
0x20000     a déclaré synchronized.

Remarque:Cela n'a aucun effet sur l'exécution (à l'exception de la réflexion de cet indicateur, en soi).

* Autorisé uniquement pour les annotations InnerClass et ne doit jamais être activé dans un class_def_item.

Encodage UTF-8 modifié

Pour faciliter la compatibilité avec les anciennes versions, le format .dex encode ses données de chaîne dans un format UTF-8 modifié standard de facto, ci-après appelé MUTF-8. Ce format est identique à l'UTF-8 standard, à l'exception des points suivants:

  • Seuls les encodages à un, deux et trois octets sont utilisés.
  • Les points de code compris dans la plage U+10000 à U+10ffff sont encodés en tant que paire de valeurs de substitution, chacune représentée par une valeur encodée sur trois octets.
  • Le point de code U+0000 est encodé sous forme de deux octets.
  • Une octet nulle simple (valeur 0) indique la fin d'une chaîne, comme c'est l'interprétation standard du langage C.

Les deux premiers éléments ci-dessus peuvent se résumer comme suit: MUTF-8 est un format d'encodage pour UTF-16, au lieu d'être un format d'encodage plus direct pour les caractères Unicode.

Les deux derniers éléments ci-dessus permettent d'inclure simultanément le point de code U+0000 dans une chaîne et de le manipuler toujours en tant que chaîne terminée par un caractère nul de style C.

Toutefois, l'encodage spécial de U+0000 signifie que, contrairement à l'UTF-8 normal, le résultat de l'appel de la fonction C standard strcmp() sur une paire de chaînes MUTF-8 n'indique pas toujours le résultat correctement signé de la comparaison de chaînes inégales. Lorsque l'ordre (et non seulement l'égalité) est un problème, le moyen le plus simple de comparer des chaînes MUTF-8 consiste à les décoder caractère par caractère, puis à comparer les valeurs décodées. (Toutefois, des implémentations plus intelligentes sont également possibles.)

Pour en savoir plus sur l'encodage des caractères, consultez la norme Unicode. MUTF-8 est en fait plus proche de l'encodage CESU-8 (relativement moins connu) que de l'encodage UTF-8 en lui-même.

Encodage de encoded_value

Intégré dans annotation_element et encoded_array_item

Un encoded_value est un élément de données structurées de manière hiérarchique (presque) arbitraire et encodé. L'encodage doit être à la fois compact et simple à analyser.

Nom Format Description
(value_arg << 5) | value_type ubyte octet indiquant le type de l'value immédiatement suivant, ainsi qu'un argument facultatif de clarification dans les trois bits de poids fort. Vous trouverez ci-dessous les différentes définitions de value. Dans la plupart des cas, value_arg encode la longueur de l'value immédiatement suivante en octets, comme (size - 1), par exemple : 0 signifie que la valeur nécessite un octet, et 7 signifie qu'elle nécessite huit octets. Toutefois, il existe des exceptions, comme indiqué ci-dessous.
value ubyte[] octets représentant la valeur, dont la longueur est variable et qui sont interprétés différemment pour les différents octets value_type, mais toujours en ordre petit endian. Pour en savoir plus, consultez les différentes définitions de valeurs ci-dessous.

Formats de valeur

Nom du type value_type Format value_arg Format value Description
VALUE_BYTE 0x00 (aucun ; doit être 0) ubyte[1] valeur entière signée d'un octet
VALUE_SHORT 0x02 taille - 1 (0…1) ubyte[size] Valeur entière signée de deux octets, avec extension du signe
VALUE_CHAR 0x03 taille - 1 (0…1) ubyte[size] Valeur entière non signée de deux octets, étendue à zéro
VALUE_INT 0x04 taille - 1 (0 à 3) ubyte[size] Valeur entière signée de quatre octets, avec extension du signe
VALUE_LONG 0x06 taille - 1 (0 à 7) ubyte[size] Valeur entière signée sur huit octets, avec extension du signe
VALUE_FLOAT 0x10 taille - 1 (0 à 3) ubyte[size] Format de bits de quatre octets, étendu à zéro à droite et interprété comme une valeur à virgule flottante IEEE754 32 bits
VALUE_DOUBLE 0x11 taille - 1 (0 à 7) ubyte[size] Format de bits de huit octets, étendu à zéro à droite et interprété comme une valeur à virgule flottante IEEE754 64 bits
VALUE_METHOD_TYPE 0x15 taille - 1 (0 à 3) ubyte[size] Valeur entière de quatre octets non signée (étendue à zéro), interprétée comme un indice dans la section proto_ids et représentant une valeur de type de méthode
VALUE_METHOD_HANDLE 0x16 taille - 1 (0…3) ubyte[size] Valeur entière de quatre octets non signée (étendue à zéro), interprétée comme un indice dans la section method_handles et représentant une valeur de poignée de méthode
VALUE_STRING 0x17 taille - 1 (0 à 3) ubyte[size] Valeur entière de quatre octets non signée (étendue à zéro), interprétée comme un indice dans la section string_ids et représentant une valeur de chaîne
VALUE_TYPE 0x18 taille - 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un indice dans la section type_ids et représentant une valeur de type/classe réfléchissante
VALUE_FIELD 0x19 taille - 1 (0 à 3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un indice dans la section field_ids et représentant une valeur de champ réfléchissante
VALUE_METHOD 0x1a taille - 1 (0 à 3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un indice dans la section method_ids et représentant une valeur de méthode réfléchissante
VALUE_ENUM 0x1b taille - 1 (0…3) ubyte[size] Valeur entière non signée (étendue à zéro) de quatre octets, interprétée comme un indice dans la section field_ids et représentant la valeur d'une constante de type énuméré
VALUE_ARRAY 0x1c (aucun ; doit être 0) encoded_array Un tableau de valeurs, au format spécifié par "encoded_array format" ci-dessous. La taille de l'value est implicite dans l'encodage.
VALUE_ANNOTATION 0x1d (aucun ; doit être 0) encoded_annotation une sous-annotation, au format spécifié par "encoded_annotation format" ci-dessous. La taille de l'value est implicite dans l'encodage.
VALUE_NULL 0x1e (aucun ; doit être 0) (aucune) Valeur de référence null
VALUE_BOOLEAN 0x1f booléen (0 à 1) (aucune) Valeur à un bit : 0 pour false et 1 pour true. Le bit est représenté dans value_arg.

Format encoded_array

Nom Format Description
taille uleb128 nombre d'éléments du tableau
valeurs encoded_value[taille] une série de séquences d'octets encoded_value size au format spécifié par cette section, concatenadas de manière séquentielle.

Format encoded_annotation

Nom Format Description
type_idx uleb128 type de l'annotation. Il doit s'agir d'un type de classe (et non de tableau ni de primitif).
taille uleb128 Nombre de mappages nom-valeur dans cette annotation
éléments annotation_element[size] éléments de l'annotation, représentés directement en ligne (et non en décalage). Les éléments doivent être triés par ordre croissant par indice string_id.

Format annotation_element

Nom Format Description
name_idx uleb128 nom de l'élément, représenté sous la forme d'un indice dans la section string_ids. La chaîne doit être conforme à la syntaxe de MemberName, définie ci-dessus.
value encoded_value valeur de l'élément

Syntaxe des chaînes

Un fichier .dex contient plusieurs types d'éléments qui font finalement référence à une chaîne. Les définitions de style BNF suivantes indiquent la syntaxe acceptable pour ces chaînes.

SimpleName

Un SimpleName est la base de la syntaxe des noms d'autres éléments. Le format .dex offre une certaine marge de manœuvre (beaucoup plus que la plupart des langues sources courantes). En résumé, un nom simple se compose de tout caractère alphabétique ou chiffre ASCII bas de gamme, de quelques symboles ASCII bas de gamme spécifiques et de la plupart des points de code non ASCII qui ne sont pas des caractères de contrôle, d'espace ou spéciaux. À partir de la version 040, le format autorise également les caractères d'espace (catégorie Unicode Zs). Notez que les points de code de substitution (dans la plage U+d800 à U+dfff) ne sont pas considérés comme des caractères de nom valides en soi, mais que les caractères supplémentaires Unicode sont valides (qui sont représentés par l'alternative finale de la règle pour SimpleNameChar), et qu'ils doivent être représentés dans un fichier sous forme de paires de points de code de substitution dans l'encodage MUTF-8.

SimpleName
SimpleNameChar (SimpleNameChar)*
SimpleNameChar →
'A''Z'
| 'a''z'
| '0''9'
| ' ' depuis la version 040 de DEX
| '$'
| '-'
| '_'
| U+00a0 depuis la version 040 de DEX
| U+00a1U+1fff
| U+2000U+200a depuis la version 040 de DEX
| U+2010U+2027
| U+202f depuis la version 040 de DEX
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

MemberName

utilisé par field_id_item et method_id_item

Un MemberName est le nom d'un membre d'une classe, les membres étant des champs, des méthodes et des classes internes.

MemberName
SimpleName
| '<' SimpleName '>'

FullClassName

Un FullClassName est un nom de classe complet, y compris un spécificateur de package facultatif suivi d'un nom obligatoire.

FullClassName →
OptionalPackagePrefix SimpleName
OptionalPackagePrefix →
(SimpleName '/')*

TypeDescriptor

Utilisé par type_id_item

Un TypeDescriptor est la représentation de n'importe quel type, y compris les primitifs, les classes, les tableaux et void. Vous trouverez ci-dessous la signification des différentes versions.

TypeDescriptor →
'V'
| FieldTypeDescriptor
FieldTypeDescriptor →
NonArrayFieldTypeDescriptor
| ('[' * 1 à 255) NonArrayFieldTypeDescriptor
NonArrayFieldTypeDescriptor
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L' FullClassName ';'

ShortyDescriptor

Utilisé par proto_id_item

Un ShortyDescriptor est la représentation courte d'un prototype de méthode, y compris les types de retour et de paramètre, à l'exception qu'il n'y a pas de distinction entre les différents types de référence (classe ou tableau). Au lieu de cela, tous les types de références sont représentés par un seul caractère 'L'.

ShortyDescriptor →
ShortyReturnType (ShortyFieldType)*
ShortyReturnType →
'V'
| ShortyFieldType
ShortyFieldType
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'

Sémantique de TypeDescriptor

C'est la signification de chacune des variantes de TypeDescriptor.

Syntaxe Signification
V void : uniquement valide pour les types de retour
Z boolean
B byte
S short
C char
I int
J long
F float
D double
Lnom complet ; la classe fully.qualified.Name
[descriptor Tableau de descriptor, utilisable de manière récursive pour les tableaux de tableaux, bien qu'il ne soit pas valide d'avoir plus de 255 dimensions.

Éléments et structures associées

Cette section inclut des définitions pour chacun des éléments de niveau supérieur pouvant apparaître dans un fichier .dex.

header_item

S'affiche dans la section d'en-tête

Alignement: 4 octets

Nom Format Description
magique ubyte[8] = DEX_FILE_MAGIC valeur magique. Pour en savoir plus, consultez la discussion ci-dessus sous "DEX_FILE_MAGIC".
somme de contrôle uint Somme de contrôle adler32 du reste du fichier (tout sauf magic et ce champ) ; permet de détecter la corruption du fichier
signature ubyte[20] Signature SHA-1 (hachage) du reste du fichier (tout sauf magic, checksum et ce champ) ; permet d'identifier de manière unique les fichiers
file_size uint

taille de l'intégralité du fichier (y compris l'en-tête), en octets (version 40 ou antérieure)

Distance en octets entre le début de cet en-tête et l'en-tête suivant ou la fin de l'ensemble du fichier (le conteneur). (version 41 ou ultérieure)

header_size uint

taille de l'en-tête (cette section entière), en octets. Cela permet d'assurer au moins une certaine rétrocompatibilité/compatibilité ascendante sans invalider le format.

doit être 0x70 (112) octets (version 40 ou antérieure)

doit être de 0x78 (120) octets (version 41 ou ultérieure)

endian_tag uint = ENDIAN_CONSTANT balise d'endianité. Pour en savoir plus, consultez la discussion ci-dessus sous "ENDIAN_CONSTANT et REVERSE_ENDIAN_CONSTANT".
link_size uint taille de la section de lien, ou 0 si ce fichier n'est pas lié de manière statique
link_off uint décalage entre le début du fichier et la section de lien, ou 0 si link_size == 0. Si le décalage est différent de zéro, il doit correspondre à un décalage dans la section link_data. Le format des données pointées n'est pas spécifié dans ce document. Ce champ d'en-tête (et le précédent) sont laissés en tant qu'hooks à utiliser par les implémentations d'exécution.
map_off uint décalage entre le début du fichier et l'élément de carte. Le décalage, qui doit être différent de zéro, doit correspondre à un décalage dans la section data, et les données doivent être au format spécifié par "map_list" ci-dessous.
string_ids_size uint nombre de chaînes dans la liste des identifiants de chaîne
string_ids_off uint décalage à partir du début du fichier jusqu'à la liste des identifiants de chaîne, ou 0 si string_ids_size == 0 (il s'agit d'un cas particulier étrange). Si le décalage n'est pas nul, il doit correspondre au début de la section string_ids.
type_ids_size uint Nombre d'éléments dans la liste des identifiants de type, au maximum 65 535
type_ids_off uint décalage à partir du début du fichier jusqu'à la liste des identifiants de type, ou 0 si type_ids_size == 0 (il s'agit d'un cas particulier étrange). Si le décalage n'est pas nul, il doit correspondre au début de la section type_ids.
proto_ids_size uint nombre d'éléments dans la liste des identifiants de prototype, au maximum 65 535
proto_ids_off uint décalage à partir du début du fichier jusqu'à la liste des identifiants de prototype, ou 0 si proto_ids_size == 0 (il s'agit d'un cas particulier étrange). Si le décalage n'est pas nul, il doit correspondre au début de la section proto_ids.
field_ids_size uint Nombre d'éléments dans la liste des identifiants de champ
field_ids_off uint décalage à partir du début du fichier jusqu'à la liste des identifiants de champ, ou 0 si field_ids_size == 0. Si le décalage est différent de zéro, il doit correspondre au début de la section field_ids.
method_ids_size uint Nombre d'éléments dans la liste des identifiants de méthode
method_ids_off uint décalage à partir du début du fichier jusqu'à la liste des identifiants de méthode, ou 0 si method_ids_size == 0. Si le décalage est différent de zéro, il doit correspondre au début de la section method_ids.
class_defs_size uint nombre d'éléments dans la liste des définitions de classe
class_defs_off uint décalage du début du fichier à la liste des définitions de classe, ou 0 si class_defs_size == 0 (il s'agit d'un cas particulier étrange). Si le décalage n'est pas nul, il doit correspondre au début de la section class_defs.
data_size uint

Taille de la section data en octets. Doit être un multiple pair de sizeof(uint). (version 40 ou antérieure)

Inutilisé (version 41 ou ultérieure)

data_off uint

décalage entre le début du fichier et le début de la section data (version 40 ou antérieure)

Inutilisé (version 41 ou ultérieure)

container_size uint

ce champ n'existe pas. On peut supposer qu'il est égal à file_size. (version 40 ou antérieure)

taille de l'ensemble du fichier (y compris les autres en-têtes dex et leurs données). (version 41 ou ultérieure)

header_offset uint

ce champ n'existe pas. On peut supposer qu'il est égal à 0. (version 40 ou antérieure)

décalage entre le début du fichier et le début de cet en-tête. (version 41 ou ultérieure)

map_list

S'affiche dans la section "Données"

Référencé à partir de header_item

Alignement: 4 octets

Il s'agit d'une liste de l'intégralité du contenu d'un fichier, dans l'ordre. Il contient une certaine redondance par rapport à header_item, mais il est conçu pour être un formulaire facile à utiliser pour itérer sur un fichier entier. Un type donné ne doit apparaître qu'une seule fois dans une carte, mais il n'existe aucune restriction sur les types d'ordres pouvant apparaître, à l'exception des restrictions implicites du reste du format (par exemple, une section header doit apparaître en premier, suivie d'une section string_ids, etc.). De plus, les entrées de la carte doivent être triées par décalage initial et ne doivent pas se chevaucher.

Nom Format Description
taille uint taille de la liste, en entrées
liste map_item[size] éléments de la liste ;

Format map_item

Nom Format Description
type ushort type des éléments (voir tableau ci-dessous)
unused ushort (inutilisé)
taille uint Nombre d'éléments à trouver au décalage indiqué
compensés en carbone uint décalage par rapport au début du fichier jusqu'aux éléments en question

Codes de type

Type d'article Constante Valeur Taille de l'élément en octets
header_item TYPE_HEADER_ITEM 0x0000 0x70
string_id_item TYPE_STRING_ID_ITEM 0x0001 0x04
type_id_item TYPE_TYPE_ID_ITEM 0x0002 0x04
proto_id_item TYPE_PROTO_ID_ITEM 0x0003 0x0c
field_id_item TYPE_FIELD_ID_ITEM 0x0004 0x08
method_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
method_handle_item TYPE_METHOD_HANDLE_ITEM 0x0008 0x08
map_list TYPE_MAP_LIST 0x1000 4 + (item.size * 12)
type_list TYPE_TYPE_LIST 0x1001 4 + (item.size * 2)
annotation_set_ref_list TYPE_ANNOTATION_SET_REF_LIST 0x1002 4 + (item.size * 4)
annotation_set_item TYPE_ANNOTATION_SET_ITEM 0x1003 4 + (item.size * 4)
class_data_item TYPE_CLASS_DATA_ITEM 0x2000 implicite ; doit être analysé
code_item TYPE_CODE_ITEM 0x2001 implicite ; doit être analysé
string_data_item TYPE_STRING_DATA_ITEM 0x2002 implicite ; doit être analysé
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 implicite ; doit être analysé
annotation_item TYPE_ANNOTATION_ITEM 0x2004 implicite ; doit être analysé
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 implicite ; doit être analysé
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 implicite ; doit être analysé
hiddenapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 implicite ; doit être analysé

string_id_item

Apparaît dans la section "string_ids"

Alignement: 4 octets

Nom Format Description
string_data_off uint décalage à partir du début du fichier jusqu'aux données de chaîne pour cet élément. Le décalage doit correspondre à un emplacement dans la section data, et les données doivent être au format spécifié par "string_data_item" ci-dessous. Il n'existe aucune exigence d'alignement pour le décalage.

string_data_item

S'affiche dans la section "Données"

Alignement: aucun (aligné sur octet)

Nom Format Description
utf16_size uleb128 taille de cette chaîne, en unités de code UTF-16 (qui correspond à la "longueur de la chaîne" dans de nombreux systèmes). Il s'agit de la longueur décodée de la chaîne. (La longueur encodée est implicite par la position de l'octet 0.)
de données ubyte[] une série d'unités de code MUTF-8 (également appelées octets ou octets) suivie d'un octet de valeur 0. Consultez la section "Encodage MUTF-8 (Modified UTF-8)" ci-dessus pour en savoir plus sur le format de données.

Remarque:Il est acceptable d'avoir une chaîne qui inclut (la forme encodée) des unités de code de substitution UTF-16 (c'est-à-dire U+d800U+dfff) soit isolément, soit dans le désordre par rapport à l'encodage habituel d'Unicode en UTF-16. C'est aux utilisations de chaînes de niveau supérieur de rejeter ces encodages non valides, le cas échéant.

type_id_item

Apparaît dans la section "type_ids"

Alignement: 4 octets

Nom Format Description
descriptor_idx uint indice dans la liste string_ids pour la chaîne de descripteur de ce type. La chaîne doit respecter la syntaxe de TypeDescriptor, définie ci-dessus.

proto_id_item

S'affiche dans la section "proto_ids"

Alignement: 4 octets

Nom Format Description
shorty_idx uint indice dans la liste string_ids pour la chaîne de descripteur abrégé de ce prototype. La chaîne doit respecter la syntaxe de ShortyDescriptor, définie ci-dessus, et correspondre au type de retour et aux paramètres de cet élément.
return_type_idx uint indice dans la liste type_ids pour le type de retour de ce prototype
parameters_off uint décalage à partir du début du fichier jusqu'à la liste des types de paramètres pour ce prototype, ou 0 si ce prototype ne comporte aucun paramètre. Si ce décalage n'est pas nul, il doit se trouver dans la section data, et les données doivent être au format spécifié par "type_list" ci-dessous. De plus, aucune référence au type void ne doit figurer dans la liste.

field_id_item

Apparaît dans la section "field_ids"

Alignement: 4 octets

Nom Format Description
class_idx ushort indice dans la liste type_ids pour le définisseur de ce champ. Il doit s'agir d'un type de classe, et non d'un tableau ou d'un type primitif.
type_idx ushort indice dans la liste type_ids pour le type de ce champ
name_idx uint indice dans la liste string_ids pour le nom de ce champ. La chaîne doit être conforme à la syntaxe de MemberName, définie ci-dessus.

method_id_item

Apparaît dans la section "method_ids" (ID de méthode)

Alignement: 4 octets

Nom Format Description
class_idx ushort indice dans la liste type_ids pour le définisseur de cette méthode. Il doit s'agir d'un type de classe ou de tableau, et non d'un type primitif.
proto_idx ushort indice dans la liste proto_ids pour le prototype de cette méthode
name_idx uint indice dans la liste string_ids pour le nom de cette méthode. La chaîne doit être conforme à la syntaxe de MemberName, définie ci-dessus.

class_def_item

S'affiche dans la section "class_defs"

Alignement: 4 octets

Nom Format Description
class_idx uint indice dans la liste type_ids pour cette classe. Il doit s'agir d'un type de classe, et non d'un tableau ou d'un type primitif.
access_flags uint indicateurs d'accès de la classe (public, final, etc.). Pour en savoir plus, consultez la section "Définitions access_flags".
superclass_idx uint indice dans la liste type_ids de la super-classe, ou valeur constante NO_INDEX si cette classe n'a pas de super-classe (c'est-à-dire qu'il s'agit d'une classe racine telle que Object). S'il est présent, il doit s'agir d'un type de classe, et non d'un tableau ou d'un type primitif.
interfaces_off uint décalage du début du fichier jusqu'à la liste des interfaces, ou 0 s'il n'y en a pas. Ce décalage doit se trouver dans la section data, et les données doivent être au format spécifié par type_list ci-dessous. Chacun des éléments de la liste doit être un type de classe (et non un tableau ou un type primitif), et il ne doit pas y avoir de doublons.
source_file_idx uint indice dans la liste string_ids pour le nom du fichier contenant la source d'origine (au moins la plupart) de cette classe, ou la valeur spéciale NO_INDEX pour indiquer l'absence de ces informations. Le debug_info_item d'une méthode donnée peut remplacer ce fichier source, mais on s'attend à ce que la plupart des classes ne proviennent que d'un seul fichier source.
annotations_off uint décalage à partir du début du fichier jusqu'à la structure d'annotations pour cette classe, ou 0 s'il n'y a pas d'annotations pour cette classe. Si ce décalage n'est pas nul, il doit se trouver dans la section data, et les données doivent être au format spécifié par annotations_directory_item ci-dessous, avec tous les éléments faisant référence à cette classe en tant que définisseur.
class_data_off uint décalage à partir du début du fichier jusqu'aux données de classe associées pour cet élément, ou 0 si aucune donnée de classe n'est associée à cette classe. (Cela peut être le cas, par exemple, si cette classe est une interface de repère.) Si le décalage n'est pas nul, il doit se trouver dans la section data, et les données doivent être au format spécifié par class_data_item ci-dessous, avec tous les éléments faisant référence à cette classe en tant que définisseur.
static_values_off uint décalage à partir du début du fichier jusqu'à la liste des valeurs initiales pour les champs static, ou 0 s'il n'y en a pas (et que tous les champs static doivent être initialisés avec 0 ou null). Ce décalage doit se trouver dans la section data, et les données doivent être au format spécifié par "encoded_array_item" ci-dessous. La taille du tableau ne doit pas dépasser le nombre de champs static déclarés par cette classe, et les éléments correspondent aux champs static dans le même ordre que celui déclaré dans le field_list correspondant. Le type de chaque élément de tableau doit correspondre au type déclaré de son champ correspondant. Si le tableau contient moins d'éléments que de champs static, les champs restants sont initialisés avec un 0 ou un null appropriés au type.

call_site_id_item

S'affiche dans la section "call_site_ids"

Alignement: 4 octets

Nom Format Description
call_site_off uint décalage par rapport au début du fichier pour appeler la définition du site. Le décalage doit se trouver dans la section des données, et les données doivent être au format spécifié par "call_site_item" ci-dessous.

call_site_item

S'affiche dans la section "Données"

Alignement: aucun (aligné sur octet)

call_site_item est un encoded_array_item dont les éléments correspondent aux arguments fournis à une méthode de linker de démarrage. Les trois premiers arguments sont les suivants:

  1. Un handle de méthode représentant la méthode du linker de démarrage (VALUE_METHOD_HANDLE).
  2. Nom de méthode que le linker de démarrage doit résoudre (VALUE_STRING).
  3. Type de méthode correspondant au type du nom de la méthode à résoudre (VALUE_METHOD_TYPE).

Les arguments supplémentaires sont des valeurs constantes transmises à la méthode du linker de démarrage. Ces arguments sont transmis dans l'ordre et sans conversion de type.

Le gestionnaire de méthode représentant la méthode du linker d'amorçage doit avoir le type de retour java.lang.invoke.CallSite. Les trois premiers types de paramètres sont les suivants:

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

Les types de paramètres de tous les arguments supplémentaires sont déterminés à partir de leurs valeurs constantes.

method_handle_item

S'affiche dans la section "method_handles"

Alignement: 4 octets

Nom Format Description
method_handle_type ushort type du gestionnaire de méthode ; voir tableau ci-dessous
unused ushort (inutilisé)
field_or_method_id ushort ID de champ ou de méthode, selon que le type de poignée de méthode est un accesseur ou un invocateur de méthode
unused ushort (inutilisé)

Codes de type de poignée de méthode

Constante Valeur Description
METHOD_HANDLE_TYPE_STATIC_PUT 0x00 Le handle de méthode est un setter de champ statique (accesseur)
METHOD_HANDLE_TYPE_STATIC_GET 0x01 Le handle de méthode est un getter de champ statique (accesseur)
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 Le handle de méthode est un setter de champ d'instance (accesseur)
METHOD_HANDLE_TYPE_INSTANCE_GET 0x03 Le gestionnaire de méthode est un accesseur (getter) de champ d'instance
METHOD_HANDLE_TYPE_INVOKE_STATIC 0x04 Le handle de méthode est un invocateur de méthode statique
METHOD_HANDLE_TYPE_INVOKE_INSTANCE 0x05 Le handle de méthode est un invocateur de méthode d'instance
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR 0x06 Le gestionnaire de méthode est un invocateur de méthode de constructeur
METHOD_HANDLE_TYPE_INVOKE_DIRECT 0x07 Le gestionnaire de méthode est un invocateur de méthode direct
METHOD_HANDLE_TYPE_INVOKE_INTERFACE 0x08 Le handle de méthode est un invocateur de méthode d'interface

class_data_item

Référencé à partir de class_def_item

S'affiche dans la section "Données"

Alignement: aucun (aligné sur octet)

Nom Format Description
static_fields_size uleb128 le nombre de champs statiques définis dans cet élément
instance_fields_size uleb128 Nombre de champs d'instance définis dans cet élément
direct_methods_size uleb128 le nombre de méthodes directes définies dans cet élément
virtual_methods_size uleb128 le nombre de méthodes virtuelles définies dans cet élément
static_fields encoded_field[static_fields_size] les champs statiques définis, représentés sous la forme d'une séquence d'éléments encodés. Les champs doivent être triés par field_idx dans l'ordre croissant.
instance_fields encoded_field[instance_fields_size] les champs d'instance définis, représentés sous la forme d'une séquence d'éléments encodés. Les champs doivent être triés par field_idx dans l'ordre croissant.
direct_methods encoded_method[direct_methods_size] les méthodes directes définies (static, private ou constructeur), représentées sous la forme d'une séquence d'éléments encodés. Les méthodes doivent être triées par method_idx dans l'ordre croissant.
virtual_methods encoded_method[virtual_methods_size] les méthodes virtuelles définies (aucune de static, private ou constructeur), représentées sous la forme d'une séquence d'éléments encodés. Cette liste ne doit pas inclure les méthodes héritées, sauf si elles sont remplacées par la classe que cet élément représente. Les méthodes doivent être triées par method_idx dans l'ordre croissant. Le method_idx d'une méthode virtuelle ne doit pas être identique à celui d'une méthode directe.

Remarque:Toutes les instances field_id et method_id des éléments doivent faire référence à la même classe de définition.

Format de encoded_field

Nom Format Description
field_idx_diff uleb128 indice dans la liste field_ids pour l'identité de ce champ (inclut le nom et le descripteur), représenté comme une différence par rapport à l'indice de l'élément précédent de la liste. L'index du premier élément d'une liste est représenté directement.
access_flags uleb128 indicateurs d'accès pour le champ (public, final, etc.). Pour en savoir plus, consultez la section "Définitions access_flags".

Format encoded_method

Nom Format Description
method_idx_diff uleb128 indice dans la liste method_ids pour l'identité de cette méthode (inclut le nom et le descripteur), représenté comme une différence par rapport à l'indice de l'élément précédent de la liste. L'index du premier élément d'une liste est représenté directement.
access_flags uleb128 indicateurs d'accès pour la méthode (public, final, etc.). Pour en savoir plus, consultez la section "Définitions access_flags".
code_off uleb128 décalage du début du fichier à la structure de code de cette méthode, ou 0 si cette méthode est abstract ou native. Le décalage doit correspondre à un emplacement de la section data. Le format des données est spécifié par "code_item" ci-dessous.

type_list

Références de class_def_item et proto_id_item

S'affiche dans la section "Données"

Alignement: 4 octets

Nom Format Description
taille uint taille de la liste, en entrées
liste type_item[size] éléments de la liste ;

Format type_item

Nom Format Description
type_idx ushort indice dans la liste type_ids

code_item

Référencé à partir de encoded_method

S'affiche dans la section "Données"

Alignement: 4 octets

Nom Format Description
registers_size ushort Nombre de registres utilisés par ce code
ins_size ushort Nombre de mots des arguments entrants de la méthode à laquelle ce code est destiné
outs_size ushort Nombre de mots d'espace d'argument sortant requis par ce code pour l'appel de méthode
tries_size ushort le nombre d'try_item pour cette instance. Si la valeur n'est pas nulle, elle apparaît sous la forme du tableau tries juste après insns dans cette instance.
debug_info_off uint Décalage à partir du début du fichier jusqu'à la séquence d'informations de débogage (numéros de ligne + informations sur les variables locales) pour ce code, ou 0 s'il n'y a tout simplement aucune information. Si le décalage n'est pas nul, il doit correspondre à un emplacement dans la section data. Le format des données est spécifié par "debug_info_item" ci-dessous.
insns_size uint taille de la liste d'instructions, en unités de code 16 bits
insns ushort[insns_size] tableau de bytecode réel. Le format du code dans un tableau insns est spécifié par le document associé Bytecode Dalvik. Notez que bien que cela soit défini comme un tableau de ushort, certaines structures internes préfèrent l'alignement sur quatre octets. De plus, si cela se trouve dans un fichier à ordre d'octets inversé, le swap n'est effectué que sur les instances ushort individuelles et non sur les structures internes plus importantes.
padding ushort (facultatif) = 0 deux octets de marge intérieure pour aligner tries sur quatre octets. Cet élément n'est présent que si tries_size est différent de zéro et que insns_size est impair.
tentatives try_item[tries_size] (facultatif) tableau indiquant où dans le code les exceptions sont détectées et comment les gérer. Les éléments du tableau ne doivent pas se chevaucher dans la plage et doivent être triés de l'adresse la plus basse à la plus élevée. Cet élément n'est présent que si tries_size est différent de zéro.
gestionnaires encoded_catch_handler_list (facultatif) octets représentant une liste de listes de types de capture et d'adresses de gestionnaires associées. Chaque try_item possède un décalage par octet dans cette structure. Cet élément n'est présent que si tries_size est différent de zéro.

Format try_item

Nom Format Description
start_addr uint adresse de début du bloc de code couvert par cette entrée. L'adresse correspond au nombre d'unités de code 16 bits jusqu'au début de la première instruction couverte.
insn_count ushort Nombre d'unités de code 16 bits couvertes par cette entrée. La dernière unité de code couverte (inclusive) est start_addr + insn_count - 1.
handler_off ushort Décalage en octets du début de l'encoded_catch_hander_list associé à l'encoded_catch_handler de cette entrée. Il doit s'agir d'un décalage par rapport au début d'un encoded_catch_handler.

Format encoded_catch_handler_list

Nom Format Description
taille uleb128 taille de cette liste, en entrées
liste encoded_catch_handler[handlers_size] liste réelle des listes de gestionnaires, représentée directement (et non sous forme d'offsets) et concaténée de manière séquentielle

Format encoded_catch_handler

Nom Format Description
taille sleb128 nombre de types de prises dans cette liste. Si la valeur n'est pas positive, il s'agit du négatif du nombre de types de captures, et les captures sont suivies d'un gestionnaire de type "tout-à-fait". Par exemple: Une size de 0 signifie qu'il existe une exception catch-all, mais aucune exception explicitement typée. Un size de 2 signifie qu'il existe deux captures explicitement typées et aucune exception. Un size de -1 signifie qu'il existe une exception saisie avec une exception globale.
gestionnaires encoded_type_addr_pair[abs(size)] Flux d'éléments encodés abs(size), un pour chaque type détecté, dans l'ordre dans lequel les types doivent être testés.
catch_all_addr uleb128 (facultatif) Adresse du bytecode du gestionnaire d'alias collecteur. Cet élément n'est présent que si size n'est pas positif.

Format encoded_type_addr_pair

Nom Format Description
type_idx uleb128 indice dans la liste type_ids pour le type d'exception à intercepter
addr uleb128 Adresse de bytecode du gestionnaire d'exceptions associé

debug_info_item

Référencé à partir de code_item

S'affiche dans la section "Données"

Alignement: aucun (aligné sur octet)

Chaque debug_info_item définit une machine d'état codée en octets inspirée de DWARF3 qui, lors de l'interprétation, émet la table des positions et (potentiellement) les informations sur les variables locales pour un code_item. La séquence commence par un en-tête à longueur variable (dont la longueur dépend du nombre de paramètres de méthode), est suivie des bytecodes de la machine à états et se termine par un octet DBG_END_SEQUENCE.

Le schéma de machine à états se compose de cinq registres. Le registre address représente le décalage d'instruction dans le insns_item associé en unités de code 16 bits. Le registre address commence à 0 au début de chaque séquence debug_info et ne doit augmenter que de manière monotone. Le registre line représente le numéro de ligne source à associer à la prochaine entrée de table de positions émise par la machine à états. Il est initialisé dans l'en-tête de séquence et peut changer dans le sens positif ou négatif, mais ne doit jamais être inférieur à 1. Le registre source_file représente le fichier source auquel les entrées de numéro de ligne font référence. Il est initialisé sur la valeur de source_file_idx dans class_def_item. Les deux autres variables, prologue_end et epilogue_begin, sont des indicateurs booléens (initialisés sur false) qui indiquent si la prochaine position émise doit être considérée comme un prologue ou un épilogue de méthode. La machine d'état doit également suivre le nom et le type de la dernière variable locale en direct dans chaque registre pour le code DBG_RESTART_LOCAL.

L'en-tête est le suivant:

Nom Format Description
line_start uleb128 la valeur initiale du registre line de la machine à états. Ne représente pas une entrée de position réelle.
parameters_size uleb128 le nombre de noms de paramètres encodés. Il doit y en avoir un par paramètre de méthode, à l'exception de l'this d'une méthode d'instance, le cas échéant.
parameter_names uleb128p1[taille_paramètres] indice de chaîne du nom du paramètre de la méthode. Une valeur codée de NO_INDEX indique qu'aucun nom n'est disponible pour le paramètre associé. Le descripteur de type et la signature sont implicites à partir du descripteur et de la signature de la méthode.

Les valeurs du code d'octet sont les suivantes:

Nom Valeur Format Arguments Description
DBG_END_SEQUENCE 0x00 (aucune) met fin à une séquence d'informations de débogage pour un code_item
DBG_ADVANCE_PC 0x01 uleb128 addr_diff addr_diff: montant à ajouter au registre des adresses fait avancer le registre des adresses sans émettre d'entrée de position
DBG_ADVANCE_LINE 0x02 sleb128 line_diff line_diff: montant à modifier dans le registre de ligne fait avancer le registre de ligne sans émettre d'entrée de position
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num: registre contenant local
name_idx: indice de chaîne du nom
type_idx: indice de type du type
introduit une variable locale à l'adresse actuelle. name_idx ou type_idx peut être NO_INDEX pour indiquer que cette valeur est inconnue.
DBG_START_LOCAL_EXTENDED 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num: registre contenant les locaux
name_idx: indice de chaîne du nom
type_idx: indice de type du type
sig_idx: indice de chaîne de la signature de type
introduit un local avec une signature de type à l'adresse actuelle. name_idx, type_idx ou sig_idx peuvent être NO_INDEX pour indiquer que cette valeur est inconnue. (Si sig_idx est -1, cependant, les mêmes données peuvent être représentées plus efficacement à l'aide de l'opcode DBG_START_LOCAL.)

Remarque:Consultez la discussion sous "dalvik.annotation.Signature" ci-dessous pour connaître les mises en garde concernant la gestion des signatures.

DBG_END_LOCAL 0x05 uleb128 register_num register_num: registre contenant le local marque une variable locale active comme hors du champ d'application à l'adresse actuelle
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: enregistrement pour redémarrer réintroduit une variable locale à l'adresse actuelle. Le nom et le type sont identiques à ceux du dernier local actif dans le registre spécifié.
DBG_SET_PROLOGUE_END 0x07 (aucune) définit le registre de la machine d'état prologue_end, indiquant que l'entrée de position suivante ajoutée doit être considérée comme la fin d'un prologue de méthode (un emplacement approprié pour un point d'arrêt de méthode). Le registre prologue_end est effacé par n'importe quel code d'instruction spécial (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (aucune) définit le registre de la machine d'état epilogue_begin, indiquant que l'entrée de position suivante ajoutée doit être considérée comme le début d'un épilogue de méthode (un emplacement approprié pour suspendre l'exécution avant la sortie de la méthode). Le registre epilogue_begin est effacé par n'importe quel code d'instruction spécial (>= 0x0a).
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: index de chaîne du nom du fichier source ; NO_INDEX en cas d'inconnu indique que toutes les entrées de numéro de ligne suivantes font référence à ce nom de fichier source, au lieu du nom par défaut spécifié dans code_item.
Opcodes spéciaux 0x0a…0xff (aucune) avance les registres line et address, émet une entrée de position et efface prologue_end et epilogue_begin. Pour en savoir plus, consultez les informations ci-dessous.

Opcodes spéciaux

Les opcodes dont la valeur est comprise entre 0x0a et 0xff (inclus) déplacent les registres line et address d'une petite quantité, puis émettent une nouvelle entrée de table de positions. La formule des incréments est la suivante:

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

Référencé à partir de class_def_item

S'affiche dans la section "Données"

Alignement: 4 octets

Nom Format Description
class_annotations_off uint décalage à partir du début du fichier jusqu'aux annotations effectuées directement sur la classe, ou 0 si la classe ne comporte aucune annotation directe. Si le décalage n'est pas nul, il doit correspondre à un emplacement dans la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.
fields_size uint Nombre de champs annotés par cet élément
annotated_methods_size uint nombre de méthodes annotées par cet élément
annotated_parameters_size uint Nombre de listes de paramètres de méthode annotées par cet élément
field_annotations field_annotation[fields_size] (facultatif) liste des annotations de champ associées. Les éléments de la liste doivent être triés par ordre croissant, par field_idx.
method_annotations method_annotation[methods_size] (facultatif) liste des annotations de méthode associées. Les éléments de la liste doivent être triés par ordre croissant, par method_idx.
parameter_annotations parameter_annotation[parameters_size] (facultatif) liste des annotations de paramètres de méthode associées. Les éléments de la liste doivent être triés par ordre croissant, par method_idx.

Remarque:Toutes les instances field_id et method_id des éléments doivent faire référence à la même classe de définition.

Format de field_annotation

Nom Format Description
field_idx uint indice dans la liste field_ids pour l'identité du champ annoté
annotations_off uint décalage à partir du début du fichier jusqu'à la liste des annotations pour le champ. Le décalage doit correspondre à un emplacement de la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.

Format de method_annotation

Nom Format Description
method_idx uint indice dans la liste method_ids pour l'identité de la méthode annotée
annotations_off uint décalage à partir du début du fichier jusqu'à la liste des annotations pour la méthode. Le décalage doit correspondre à un emplacement de la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.

Format de l'annotation "parameter"

Nom Format Description
method_idx uint indice dans la liste method_ids pour l'identité de la méthode dont les paramètres sont annotés
annotations_off uint décalage à partir du début du fichier jusqu'à la liste des annotations pour les paramètres de la méthode. Le décalage doit correspondre à un emplacement de la section data. Le format des données est spécifié par "annotation_set_ref_list" ci-dessous.

annotation_set_ref_list

Référence de parameter_annotations_item

S'affiche dans la section "Données"

Alignement: 4 octets

Nom Format Description
taille uint taille de la liste, en entrées
liste annotation_set_ref_item[size] éléments de la liste ;

Format annotation_set_ref_item

Nom Format Description
annotations_off uint décalage à partir du début du fichier jusqu'à l'ensemble d'annotations référencé ou 0 si aucune annotation n'est associée à cet élément. Si le décalage n'est pas nul, il doit correspondre à un emplacement dans la section data. Le format des données est spécifié par "annotation_set_item" ci-dessous.

annotation_set_item

Référencé à partir de annotations_directory_item, field_annotations_item, method_annotations_item et annotation_set_ref_item

S'affiche dans la section "Données"

Alignement: 4 octets

Nom Format Description
taille uint taille de l'ensemble, en entrées
entrées annotation_off_item[taille] éléments de l'ensemble. Les éléments doivent être triés par ordre croissant, par type_idx.

Format annotation_off_item

Nom Format Description
annotation_off uint décalage du début du fichier à une annotation. Le décalage doit correspondre à un emplacement dans la section data, et le format des données à cet emplacement est spécifié par "annotation_item" ci-dessous.

annotation_item

Référencé à partir de annotation_set_item

S'affiche dans la section "Données"

Alignement: aucun (aligné sur octet)

Nom Format Description
visibilité ubyte visibilité prévue de cette annotation (voir ci-dessous)
annotation encoded_annotation Contenu d'annotation encodé, au format décrit par "encoded_annotation format" sous "encoded_value encoding" ci-dessus.

Valeurs de visibilité

Voici les options pour le champ visibility dans un annotation_item:

Nom Valeur Description
VISIBILITY_BUILD 0x00 ne sont destinés à être visibles qu'au moment de la compilation (par exemple, lors de la compilation d'un autre code) ;
VISIBILITY_RUNTIME 0x01 destinés à être visibles au moment de l'exécution
VISIBILITY_SYSTEM 0x02 destinés à être visibles au moment de l'exécution, mais uniquement par le système sous-jacent (et non par le code utilisateur standard)

encoded_array_item

Référencé à partir de class_def_item

S'affiche dans la section "Données"

Alignement: aucun (aligné sur octet)

Nom Format Description
value encoded_array octets représentant la valeur du tableau encodé, au format spécifié par "encoded_array Format" (Format encoded_array) sous "encoded_value Encoding" (Encodage encoded_value) ci-dessus.

hiddenapi_class_data_item

Cette section contient des données sur les interfaces limitées utilisées par chaque classe.

Remarque:La fonctionnalité d'API masquée a été introduite dans Android 10.0 et ne s'applique qu'aux fichiers DEX des classes dans le chemin d'accès des classes de démarrage. La liste des indicateurs décrite ci-dessous peut être étendue dans les prochaines versions d'Android. Pour en savoir plus, consultez les restrictions concernant les interfaces non SDK.

Nom Format Description
taille uint taille totale de la section
décalages uint[] Tableau d'offsets indexés par class_idx. Une entrée de tableau nulle à l'index class_idx signifie qu'il n'y a pas de données pour ce class_idx ou que tous les indicateurs d'API masqués sont nuls. Sinon, l'entrée du tableau est non nulle et contient un décalage du début de la section vers un tableau d'indicateurs d'API masqués pour ce class_idx.
indicateurs uleb128[] tableaux concaténés d'indicateurs d'API masqués pour chaque classe. Les valeurs d'indicateur possibles sont décrites dans le tableau ci-dessous. Les indicateurs sont encodés dans le même ordre que les champs et les méthodes dans les données de classe.

Types d'indicateurs de restriction:

Nom Valeur Description
liste blanche 0 Interfaces pouvant être utilisées librement et prises en charge dans l'index des packages du framework Android officiellement documenté.
liste grise 1 Interfaces non SDK pouvant être utilisées quel que soit le niveau d'API cible de l'application.
ajouter à la liste noire 2 Interfaces non SDK qui ne peuvent pas être utilisées quel que soit le niveau d'API cible de l'application. L'accès à l'une de ces interfaces entraîne une erreur d'exécution.
greylist‑max‑o 3 Interfaces non SDK pouvant être utilisées pour Android 8.x et versions antérieures, sauf si elles sont limitées.
greylist‑max‑p 4 Interfaces non SDK pouvant être utilisées pour Android 9.x, sauf si elles sont limitées.
greylist‑max‑q 5 Interfaces non SDK pouvant être utilisées pour Android 10.x, sauf si elles sont limitées.
greylist‑max‑r 6 Interfaces non SDK pouvant être utilisées pour Android 11.x, sauf si elles sont limitées.

Annotations système

Les annotations système sont utilisées pour représenter différentes informations réfléchissantes sur les classes (et les méthodes et les champs). Ces informations ne sont généralement accessibles qu'indirectement par le code client (non système).

Les annotations système sont représentées dans les fichiers .dex sous forme d'annotations dont la visibilité est définie sur VISIBILITY_SYSTEM.

dalvik.annotation.AnnotationDefault

S'affiche sur les méthodes dans les interfaces d'annotation

Une annotation AnnotationDefault est associée à chaque interface d'annotation qui souhaite indiquer les liaisons par défaut.

Nom Format Description
value Annotation les liaisons par défaut pour cette annotation, représentées sous la forme d'une annotation de ce type. L'annotation n'a pas besoin d'inclure tous les noms définis par l'annotation. Les noms manquants n'ont pas de valeurs par défaut.

dalvik.annotation.EnclosingClass

Figure sur les cours

Une annotation EnclosingClass est associée à chaque classe définie en tant que membre d'une autre classe, en soi, ou anonyme, mais non définie dans le corps d'une méthode (par exemple, une classe interne synthétique). Chaque classe qui comporte cette annotation doit également comporter une annotation InnerClass. De plus, une classe ne doit pas comporter à la fois une annotation EnclosingClass et une annotation EnclosingMethod.

Nom Format Description
value Classe la classe qui définit le plus précisément le champ lexical de cette classe

dalvik.annotation.EnclosingMethod

Figure sur les cours

Une annotation EnclosingMethod est associée à chaque classe définie dans le corps d'une méthode. Chaque classe qui comporte cette annotation doit également comporter une annotation InnerClass. De plus, une classe ne doit pas comporter à la fois une annotation EnclosingClass et une annotation EnclosingMethod.

Nom Format Description
value Méthode la méthode qui définit le plus précisément le champ lexical de cette classe

dalvik.annotation.InnerClass

Figure sur les cours

Une annotation InnerClass est associée à chaque classe définie dans le champ lexical de la définition d'une autre classe. Toute classe qui comporte cette annotation doit également comporter soit une annotation EnclosingClass ou une annotation EnclosingMethod.

Nom Format Description
nom Chaîne nom simple déclaré à l'origine de cette classe (sans préfixe de package). Si cette classe est anonyme, le nom est null.
accessFlags int les indicateurs d'accès déclarés à l'origine de la classe (qui peuvent différer des indicateurs efficaces en raison d'une incompatibilité entre les modèles d'exécution de la langue source et de la machine virtuelle cible)

dalvik.annotation.MemberClasses

Figure sur les cours

Une annotation MemberClasses est associée à chaque classe qui déclare des classes membres. (Une classe membre est une classe interne directe qui possède un nom.)

Nom Format Description
value Class[] tableau des classes de membres

dalvik.annotation.MethodParameters

S'affiche sur les méthodes

Remarque:Cette annotation a été ajoutée après Android 7.1. Sa présence sur les versions antérieures d'Android sera ignorée.

Une annotation MethodParameters est facultative et peut être utilisée pour fournir des métadonnées de paramètre telles que des noms et des modificateurs de paramètre.

L'annotation peut être omise d'une méthode ou d'un constructeur sans risque lorsque les métadonnées de paramètre ne sont pas requises au moment de l'exécution. java.lang.reflect.Parameter.isNamePresent() permet de vérifier si des métadonnées sont présentes pour un paramètre, et les méthodes de réflexion associées telles que java.lang.reflect.Parameter.getName() reviennent au comportement par défaut au moment de l'exécution si les informations ne sont pas présentes.

Lorsque des métadonnées de paramètres sont incluses, les compilateurs doivent inclure des informations pour les classes générées telles que les énumérations, car les métadonnées de paramètres indiquent si un paramètre est synthétique ou obligatoire.

Une annotation MethodParameters ne décrit que les paramètres de méthode individuels. Par conséquent, les compilateurs peuvent omettre complètement l'annotation pour les constructeurs et les méthodes qui ne comportent aucun paramètre, pour des raisons de taille de code et d'efficacité d'exécution.

Les tableaux documentés ci-dessous doivent avoir la même taille que pour la structure dex method_id_item associée à la méthode, sinon une exception java.lang.reflect.MalformedParametersException sera générée au moment de l'exécution.

Autrement dit, method_id_item.proto_idx -> proto_id_item.parameters_off -> type_list.size doit être identique à names().length et accessFlags().length.

Étant donné que MethodParameters décrit tous les paramètres de méthode formels, même ceux qui ne sont pas déclarés explicitement ou implicitement dans le code source, la taille des tableaux peut différer de la signature ou d'autres informations de métadonnées basées uniquement sur des paramètres explicites déclarés dans le code source. MethodParameters n'inclura pas non plus d'informations sur les paramètres de récepteur d'annotation de type qui n'existent pas dans la signature de méthode réelle.

Nom Format Description
noms String[] Noms des paramètres formels de la méthode associée. Le tableau ne doit pas être nul, mais doit être vide s'il n'y a pas de paramètres formels. Une valeur du tableau doit être nulle si le paramètre formel associé à cet indice n'a pas de nom.
Si les chaînes de nom de paramètre sont vides ou contiennent ".", ";'", "[" ou "/", une exception java.lang.reflect.MalformedParametersException est générée au moment de l'exécution.
accessFlags int[] Les indicateurs d'accès des paramètres formels de la méthode associée. Le tableau ne doit pas être nul, mais doit être vide s'il n'y a pas de paramètres formels.
La valeur est un masque de bits avec les valeurs suivantes:
  • 0x0010 : final, le paramètre a été déclaré final
  • 0x1000 : synthétique, le paramètre a été introduit par le compilateur
  • 0x8000 : obligatoire, le paramètre est synthétique, mais également impliqué par la spécification de la langue
Si des bits sont définis en dehors de cet ensemble, une exception java.lang.reflect.MalformedParametersException est générée au moment de l'exécution.

dalvik.annotation.Signature

Apparaît sur les classes, les champs et les méthodes

Une annotation Signature est associée à chaque classe, champ ou méthode définie en termes d'un type plus complexe que celui qui peut être représenté par un type_id_item. Le format .dex ne définit pas le format des signatures. Il est simplement destiné à pouvoir représenter toutes les signatures qu'un langage source nécessite pour une implémentation réussie de la sémantique de ce langage. Par conséquent, les signatures ne sont généralement pas analysées (ni vérifiées) par les implémentations de machines virtuelles. Les signatures sont simplement transmises à des API et des outils de niveau supérieur (tels que des débogueurs). Par conséquent, toute utilisation d'une signature doit être écrite de manière à ne pas faire d'hypothèses sur la réception de signatures valides uniquement, et à se protéger explicitement contre la possibilité de rencontrer une signature syntaxiquement non valide.

Étant donné que les chaînes de signature ont tendance à contenir beaucoup de contenu en double, une annotation Signature est définie comme un tableau de chaînes, où les éléments en double font naturellement référence aux mêmes données sous-jacentes, et la signature est considérée comme la concaténation de toutes les chaînes du tableau. Il n'existe aucune règle sur la façon de séparer une signature en chaînes distinctes. Cela dépend entièrement des outils qui génèrent les fichiers .dex.

Nom Format Description
value String[] la signature de cette classe ou de ce membre, sous la forme d'un tableau de chaînes à concaténer

dalvik.annotation.Throws

S'affiche sur les méthodes

Une annotation Throws est associée à chaque méthode déclarée pour générer un ou plusieurs types d'exceptions.

Nom Format Description
value Class[] Tableau des types d'exceptions générés