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 |
---|---|---|---|
00 | 0 | 0 | -1 |
01 | 1 | 1 | 0 |
7f | -1 | 127 | 126 |
80 7f | -128 | 16256 | 16255 |
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
etdata_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_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). |
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+00a1 … U+1fff |
|
| | U+2000 … U+200a |
depuis la version 040 de DEX |
| | U+2010 … U+2027 |
|
| | U+202f |
depuis la version 040 de DEX |
| | U+2030 … U+d7ff |
|
| | U+e000 … U+ffef |
|
| | U+10000 … U+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 Inutilisé (version 41 ou ultérieure) |
data_off | uint |
décalage entre le début du fichier et le début de la section Inutilisé (version 41 ou ultérieure) |
container_size | uint |
ce champ n'existe pas. On peut supposer qu'il est égal à 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 à 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 |
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:
- Un handle de méthode représentant la méthode du linker de démarrage (VALUE_METHOD_HANDLE).
- Nom de méthode que le linker de démarrage doit résoudre (VALUE_STRING).
- 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:
java.lang.invoke.Lookup
java.lang.String
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 localname_idx : indice de chaîne du nomtype_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 locauxname_idx : indice de chaîne du nomtype_idx : indice de type du typesig_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 " |
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:
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 |