Este documento describe el diseño y el contenido de los archivos .dex
, que se utilizan para contener un conjunto de definiciones de clases y sus datos adjuntos asociados.
guía de tipos
Nombre | Descripción |
---|---|
byte | entero con signo de 8 bits |
ubyte | entero sin signo de 8 bits |
corto | Int con signo de 16 bits, little-endian |
corto | Int sin signo de 16 bits, little-endian |
En t | Int con signo de 32 bits, little-endian |
uint | Int sin signo de 32 bits, little-endian |
largo | Int con signo de 64 bits, little-endian |
ulong | Int sin signo de 64 bits, little-endian |
sleb128 | LEB128 firmado, longitud variable (ver más abajo) |
uleb128 | LEB128 sin firmar, longitud variable (ver más abajo) |
uleb128p1 | LEB128 sin firmar más 1 , longitud variable (ver más abajo) |
LEB128
LEB128 (" L ittle- Endian B ase 128 ") es una codificación de longitud variable para cantidades enteras arbitrarias con o sin signo. El formato fue tomado de la especificación DWARF3 . En un archivo .dex
, LEB128 sólo se utiliza para codificar cantidades de 32 bits.
Cada valor codificado LEB128 consta de uno a cinco bytes, que juntos representan un único valor de 32 bits. Cada byte tiene su bit más significativo establecido, excepto el byte final de la secuencia, que tiene su bit más significativo limpio. Los siete bits restantes de cada byte son carga útil, con los siete bits menos significativos de la cantidad en el primer byte, los siete siguientes en el segundo byte y así sucesivamente. En el caso de un LEB128 con signo ( sleb128
), el bit de carga útil más significativo del byte final de la secuencia se extiende con signo para producir el valor final. En el caso sin signo ( uleb128
), cualquier bit no representado explícitamente se interpreta como 0
.
Diagrama bit a bit de un valor LEB128 de dos bytes | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Primer byte | Segundo byte | ||||||||||||||
1 | poco 6 | poco 5 | poco 4 | poco 3 | poco 2 | poco 1 | poco 0 | 0 | poco 13 | poco 12 | poco 11 | poco 10 | poco 9 | poco 8 | poco 7 |
La variante uleb128p1
se utiliza para representar un valor con signo, donde la representación es del valor más uno codificado como uleb128
. Esto hace que la codificación de -1
(alternativamente considerado como el valor sin signo 0xffffffff
), pero ningún otro número negativo, sea de un solo byte, y es útil exactamente en aquellos casos en los que el número representado debe ser no negativo o -1
(o 0xffffffff
), y donde no se permiten otros valores negativos (o donde es poco probable que se necesiten valores grandes sin signo).
A continuación se muestran algunos ejemplos de los formatos:
Secuencia codificada | como sleb128 | como uleb128 | Como uleb128p1 |
---|---|---|---|
00 | 0 | 0 | -1 |
01 | 1 | 1 | 0 |
7f | -1 | 127 | 126 |
80 7f | -128 | 16256 | 16255 |
Diseño de archivo
Nombre | Formato | Descripción |
---|---|---|
encabezamiento | elemento_encabezado | el encabezado |
string_ids | string_id_item[] | lista de identificadores de cadenas. Estos son identificadores para todas las cadenas utilizadas por este archivo, ya sea para nombres internos (por ejemplo, descriptores de tipo) o como objetos constantes a los que hace referencia el código. Esta lista debe ordenarse por contenido de cadena, utilizando valores de puntos de código UTF-16 (no dependiendo de la configuración regional) y no debe contener entradas duplicadas. |
identificadores de tipo | tipo_id_elemento[] | lista de identificadores de tipo. Estos son identificadores para todos los tipos (clases, matrices o tipos primitivos) a los que hace referencia este archivo, ya sea que estén definidos en el archivo o no. Esta lista debe estar ordenada por índice string_id y no debe contener entradas duplicadas. |
proto_ids | proto_id_item[] | Lista de identificadores de prototipos de métodos. Estos son identificadores de todos los prototipos a los que hace referencia este archivo. Esta lista debe ordenarse en orden principal de tipo de retorno (por índice type_id ) y luego por lista de argumentos (orden lexicográfico, argumentos individuales ordenados por índice type_id ). La lista no debe contener entradas duplicadas. |
identificadores de campo | campo_id_item[] | lista de identificadores de campo. Estos son identificadores para todos los campos a los que hace referencia este archivo, ya sea que estén definidos en el archivo o no. Esta lista debe estar ordenada, donde el tipo de definición (por type_id ) es el orden principal, el nombre del campo (por índice string_id ) es el orden intermedio y el tipo (por índice type_id ) es el orden menor. La lista no debe contener entradas duplicadas. |
id_método | método_id_elemento[] | lista de identificadores de métodos. Estos son identificadores para todos los métodos a los que hace referencia este archivo, ya sea que estén definidos en el archivo o no. Esta lista debe estar ordenada, donde el tipo de definición (por type_id ) es el orden principal, el nombre del método (por índice string_id ) es el orden intermedio y el prototipo del método (por índice proto_id ) es el orden menor. La lista no debe contener entradas duplicadas. |
class_defs | class_def_item[] | lista de definiciones de clases. Las clases deben ordenarse de manera que la superclase de una clase determinada y las interfaces implementadas aparezcan en la lista antes que la clase de referencia. Además, no es válido que una definición de la clase con el mismo nombre aparezca más de una vez en la lista. |
call_site_ids | call_site_id_item[] | lista de identificadores de sitios de llamadas. Estos son identificadores para todos los sitios de llamadas a los que hace referencia este archivo, ya sea que estén definidos en el archivo o no. Esta lista debe ordenarse en orden ascendente de call_site_off . |
mangos_método | método_handle_item[] | lista de identificadores de métodos. Una lista de todos los identificadores de métodos a los que hace referencia este archivo, ya sea que estén definidos en el archivo o no. Esta lista no está ordenada y puede contener duplicados que lógicamente corresponderán a diferentes instancias de manejo de métodos. |
datos | ubyte[] | área de datos, que contiene todos los datos de soporte para las tablas enumeradas anteriormente. Diferentes elementos tienen diferentes requisitos de alineación y, si es necesario, se insertan bytes de relleno antes de cada elemento para lograr una alineación adecuada. |
enlace_datos | ubyte[] | datos utilizados en archivos vinculados estáticamente. El formato de los datos de esta sección no se especifica en este documento. Esta sección está vacía en archivos no vinculados y las implementaciones en tiempo de ejecución pueden usarla como mejor les parezca. |
Definiciones de campos de bits, cadenas y constantes
DEX_FILE_MAGIC
Incrustado en header_item
La matriz/cadena constante DEX_FILE_MAGIC
es la lista de bytes que deben aparecer al principio de un archivo .dex
para que sea reconocido como tal. El valor contiene intencionalmente una nueva línea ( "\n"
o 0x0a
) y un byte nulo ( "\0"
o 0x00
) para ayudar en la detección de ciertas formas de corrupción. El valor también codifica un número de versión de formato con tres dígitos decimales, que se espera que aumente monótonamente con el tiempo a medida que evoluciona el formato.
ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 } = "dex\n039\0"
Nota: La compatibilidad con la versión 039
del formato se agregó en la versión Android 9.0, que introdujo dos nuevos códigos de bytes, const-method-handle
y const-method-type
. (Cada uno de ellos se describe en la tabla Resumen del conjunto de códigos de bytes ). En Android 10, la versión 039
extiende el formato de archivo DEX para incluir información API oculta que solo se aplica a los archivos DEX en la ruta de clase de inicio.
Nota: La compatibilidad con la versión 038
del formato se agregó en la versión Android 8.0. La versión 038
agregó nuevos códigos de bytes ( invoke-polymorphic
e invoke-custom
) y datos para los identificadores de métodos.
Nota: La compatibilidad con la versión 037
del formato se agregó en la versión Android 7.0. Antes de la versión 037
la mayoría de las versiones de Android utilizaban la versión 035
del formato. La única diferencia entre las versiones 035
y 037
es la adición de métodos predeterminados y el ajuste de la invoke
.
Nota: Se han utilizado al menos un par de versiones anteriores del formato en versiones de software públicas ampliamente disponibles. Por ejemplo, la versión 009
se utilizó para las versiones M3 de la plataforma Android (noviembre-diciembre de 2007) y la versión 013
se utilizó para las versiones M5 de la plataforma Android (febrero-marzo de 2008). En varios aspectos, estas versiones anteriores del formato difieren significativamente de la versión descrita en este documento.
ENDIAN_CONSTANT y REVERSE_ENDIAN_CONSTANT
Incrustado en header_item
La constante ENDIAN_CONSTANT
se utiliza para indicar el endianidad del archivo en el que se encuentra. Aunque el formato .dex
estándar es little-endian, las implementaciones pueden optar por realizar el intercambio de bytes. Si una implementación encuentra un encabezado cuyo endian_tag
es REVERSE_ENDIAN_CONSTANT
en lugar de ENDIAN_CONSTANT
, sabrá que el archivo ha sido intercambiado en bytes desde la forma esperada.
uint ENDIAN_CONSTANT = 0x12345678; uint REVERSE_ENDIAN_CONSTANT = 0x78563412;
NO_ÍNDICE
Integrado en class_def_item y debug_info_item
La constante NO_INDEX
se utiliza para indicar que falta un valor de índice.
Nota: Este valor no está definido como 0
porque, de hecho, suele ser un índice válido.
El valor elegido para NO_INDEX
se puede representar como un solo byte en la codificación uleb128p1
.
uint NO_INDEX = 0xffffffff; // == -1 if treated as a signed int
definiciones de banderas de acceso
Incrustado en class_def_item, encoded_field, encoded_method e InnerClass
Los campos de bits de estas banderas se utilizan para indicar la accesibilidad y las propiedades generales de las clases y los miembros de la clase.
Nombre | Valor | Para clases (y anotaciones InnerClass ) | Para campos | Para métodos |
---|---|---|---|---|
ACC_PÚBLICO | 0x1 | public : visible en todas partes | public : visible en todas partes | public : visible en todas partes |
ACC_PRIVADO | 0x2 | private : sólo visible para definir la clase | private : sólo visible para definir la clase | private : sólo visible para definir la clase |
ACC_PROTECTED | 0x4 | protected : visible para paquetes y subclases | protected : visible para paquetes y subclases | protected : visible para paquetes y subclases |
ACC_STATIC | 0x8 | static : no está construido con una referencia externa this | static : global para definir la clase | static : no acepta this argumento |
ACC_FINAL | 0x10 | final : no subclasificable | final : inmutable después de la construcción | final : no anulable |
ACC_SYNCHRONIZED | 0x20 | synchronized : bloqueo asociado adquirido automáticamente cuando se llama a este método. Nota: Esto solo es válido para configurar cuando | ||
ACC_VOLATILE | 0x40 | volatile : reglas de acceso especiales para ayudar con la seguridad de los subprocesos | ||
ACC_BRIDGE | 0x40 | método de puente, agregado automáticamente por el compilador como un puente de tipo seguro | ||
ACC_TRANSIENT | 0x80 | transient : no se guardará mediante la serialización predeterminada | ||
ACC_VARARGS | 0x80 | El compilador debe tratar el último argumento como un argumento "resto". | ||
ACC_NATIVO | 0x100 | native : implementado en código nativo | ||
ACC_INTERFACE | 0x200 | interface : clase abstracta implementable múltiples veces | ||
ACC_ABSTRACT | 0x400 | abstract : no instanciable directamente | abstract : no implementado por esta clase | |
ACC_STRICT | 0x800 | strictfp : reglas estrictas para la aritmética de punto flotante | ||
ACC_SINTÉTICO | 0x1000 | no definido directamente en el código fuente | no definido directamente en el código fuente | no definido directamente en el código fuente |
ACC_ANNOTATION | 0x2000 | declarado como una clase de anotación | ||
ACC_ENUM | 0x4000 | declarado como un tipo enumerado | declarado como un valor enumerado | |
(no usado) | 0x8000 | |||
ACC_CONSTRUCTOR | 0x10000 | método constructor (inicializador de clase o instancia) | ||
ACC_DECLARED_ SINCRONIZADO | 0x20000 | declarado synchronized .Nota: Esto no tiene ningún efecto en la ejecución (aparte del reflejo de este indicador, per se). |
InnerClass
y nunca debe estar activado en un class_def_item
.
Codificación UTF-8 modificada
Como concesión a un soporte heredado más sencillo, el formato .dex
codifica sus datos de cadena en un formato UTF-8 modificado estándar de facto, en lo sucesivo denominado MUTF-8. Este formulario es idéntico al estándar UTF-8, excepto:
- Sólo se utilizan codificaciones de uno, dos y tres bytes.
- Los puntos de código en el rango
U+10000
…U+10ffff
se codifican como un par sustituto, cada uno de los cuales se representa como un valor codificado de tres bytes. - El punto de código
U+0000
está codificado en formato de dos bytes. - Un byte nulo simple (valor
0
) indica el final de una cadena, como es la interpretación estándar del lenguaje C.
Los dos primeros elementos anteriores se pueden resumir como: MUTF-8 es un formato de codificación para UTF-16, en lugar de ser un formato de codificación más directo para caracteres Unicode.
Los dos últimos elementos anteriores hacen posible incluir simultáneamente el punto de código U+0000
en una cadena y aún manipularlo como una cadena terminada en nulo estilo C.
Sin embargo, la codificación especial de U+0000
significa que, a diferencia del UTF-8 normal, el resultado de llamar a la función estándar de C strcmp()
en un par de cadenas MUTF-8 no siempre indica el resultado correctamente firmado de la comparación de cadenas desiguales . . Cuando el orden (no solo la igualdad) es una preocupación, la forma más sencilla de comparar cadenas MUTF-8 es decodificarlas carácter por carácter y comparar los valores decodificados. (Sin embargo, también son posibles implementaciones más inteligentes).
Consulte el estándar Unicode para obtener más información sobre la codificación de caracteres. En realidad, MUTF-8 está más cerca de la codificación (relativamente menos conocida) CESU-8 que de UTF-8 per se.
codificación de valor_codificado
Incrustado en annotation_element y encoded_array_item
Un encoded_value
es una pieza codificada de datos (casi) arbitrarios estructurados jerárquicamente. La codificación debe ser compacta y sencilla de analizar.
Nombre | Formato | Descripción |
---|---|---|
(valor_arg << 5) | tipo de valor | ubyte | byte que indica el tipo del value inmediatamente posterior junto con un argumento aclaratorio opcional en los tres bits de orden superior. Consulte a continuación las distintas definiciones value . En la mayoría de los casos, value_arg codifica la longitud del value inmediatamente posterior en bytes, como (size - 1) , por ejemplo, 0 significa que el valor requiere un byte y 7 significa que requiere ocho bytes; sin embargo, existen excepciones como se indica a continuación. |
valor | ubyte[] | bytes que representan el valor, de longitud variable y se interpretan de manera diferente para diferentes bytes value_type , aunque siempre en little-endian. Consulte las diversas definiciones de valores a continuación para obtener más detalles. |
Formatos de valor
Escribe un nombre | value_type | formato value_arg | formato value | Descripción |
---|---|---|---|---|
VALOR_BYTE | 0x00 | (ninguno; debe ser 0 ) | ubyte[1] | valor entero de un byte con signo |
VALOR_SHORT | 0x02 | tamaño - 1 (0…1) | ubyte[tamaño] | valor entero de dos bytes con signo, extendido con signo |
VALUE_CHAR | 0x03 | tamaño - 1 (0…1) | ubyte[tamaño] | valor entero de dos bytes sin signo, extendido a cero |
VALOR_INT | 0x04 | tamaño - 1 (0…3) | ubyte[tamaño] | valor entero de cuatro bytes con signo, extendido con signo |
VALUE_LONG | 0x06 | tamaño - 1 (0…7) | ubyte[tamaño] | valor entero de ocho bytes con signo, extendido con signo |
VALOR_FLOAT | 0x10 | tamaño - 1 (0…3) | ubyte[tamaño] | patrón de bits de cuatro bytes, extendido en cero hacia la derecha e interpretado como un valor de punto flotante IEEE754 de 32 bits |
VALOR_DOBLE | 0x11 | tamaño - 1 (0…7) | ubyte[tamaño] | patrón de bits de ocho bytes, extendido en cero hacia la derecha e interpretado como un valor de punto flotante IEEE754 de 64 bits |
VALUE_METHOD_TYPE | 0x15 | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección proto_ids y que representa un valor de tipo de método. |
VALUE_METHOD_HANDLE | 0x16 | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección method_handles y que representa un valor de identificador de método. |
VALUE_STRING | 0x17 | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección string_ids y que representa un valor de cadena. |
TIPO DE VALOR | 0x18 | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección type_ids y que representa un valor de tipo/clase reflectante. |
VALOR_CAMPO | 0x19 | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección field_ids y que representa un valor de campo reflectante. |
VALOR_METHOD | 0x1a | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección method_ids y que representa un valor de método reflectante. |
VALOR_ENUM | 0x1b | tamaño - 1 (0…3) | ubyte[tamaño] | Valor entero de cuatro bytes sin signo (extendido en cero), interpretado como un índice en la sección field_ids y que representa el valor de una constante de tipo enumerada. |
VALOR_ARRAY | 0x1c | (ninguno; debe ser 0 ) | matriz_codificada | una matriz de valores, en el formato especificado en "formato encoded_array " a continuación. El tamaño del value está implícito en la codificación. |
VALUE_ANNOTATION | 0x1d | (ninguno; debe ser 0 ) | anotación_codificada | una subanotación, en el formato especificado en "formato encoded_annotation " a continuación. El tamaño del value está implícito en la codificación. |
VALOR_NULL | 0x1e | (ninguno; debe ser 0 ) | (ninguno) | valor de referencia null |
VALOR_BOOLEAN | 0x1f | booleano (0…1) | (ninguno) | valor de un bit; 0 para false y 1 para true . El bit está representado en value_arg . |
formato de matriz_codificada
Nombre | Formato | Descripción |
---|---|---|
tamaño | uleb128 | número de elementos en la matriz |
valores | valor_codificado[tamaño] | una serie de secuencias de bytes encoded_value size en el formato especificado en esta sección, concatenadas secuencialmente. |
formato de anotación_codificada
Nombre | Formato | Descripción |
---|---|---|
tipo_idx | uleb128 | tipo de anotación. Debe ser un tipo de clase (no de matriz o primitivo). |
tamaño | uleb128 | número de asignaciones de nombre-valor en esta anotación |
elementos | elemento_anotación[tamaño] | elementos de la anotación, representados directamente en línea (no como compensaciones). Los elementos deben ordenarse en orden creciente según el índice string_id . |
formato elemento_anotación
Nombre | Formato | Descripción |
---|---|---|
nombre_idx | uleb128 | nombre del elemento, representado como un índice en la sección string_ids . La cadena debe ajustarse a la sintaxis de MemberName , definida anteriormente. |
valor | valor_codificado | valor del elemento |
Sintaxis de cadena
Hay varios tipos de elementos en un archivo .dex
que, en última instancia, hacen referencia a una cadena. Las siguientes definiciones de estilo BNF indican la sintaxis aceptable para estas cadenas.
Nombre simple
Un SimpleName es la base de la sintaxis de los nombres de otras cosas. El formato .dex
permite aquí una gran libertad (mucho más que la mayoría de los lenguajes fuente comunes). En resumen, un nombre simple consta de cualquier carácter o dígito alfabético de bajo ASCII, algunos símbolos específicos de bajo ASCII y la mayoría de los puntos de código no ASCII que no son caracteres de control, espacios ni especiales. A partir de la versión 040
el formato permite además caracteres de espacio (categoría Unicode Zs
). Tenga en cuenta que los puntos de código sustituto (en el rango U+d800
… U+dfff
) no se consideran caracteres de nombre válidos, per se, pero los caracteres suplementarios Unicode son válidos (que están representados por la alternativa final de la regla para SimpleNameChar ), y deben representarse en un archivo como pares de puntos de código sustituto en la codificación MUTF-8.
Nombre simple → | ||
NombreSimpleChar ( NombreSimpleChar )* | ||
SimpleNameChar → | ||
'A' ... 'Z' | ||
| | 'a' ... 'z' | |
| | '0' ... '9' | |
| | ' ' | desde DEX versión 040 |
| | '$' | |
| | '-' | |
| | '_' | |
| | U+00a0 | desde DEX versión 040 |
| | U+00a1 … U+1fff | |
| | U+2000 … U+200a | desde DEX versión 040 |
| | U+2010 … U+2027 | |
| | U+202f | desde DEX versión 040 |
| | U+2030 … U+d7ff | |
| | U+e000 … U+ffef | |
| | U+10000 … U+10ffff |
Nombre de miembro
utilizado por field_id_item y método_id_item
Un MemberName es el nombre de un miembro de una clase, siendo los miembros campos, métodos y clases internas.
Nombre de miembro → | |
Nombre simple | |
| | '<' Nombre simple '>' |
Nombre de clase completo
Un FullClassName es un nombre de clase completo, que incluye un especificador de paquete opcional seguido de un nombre obligatorio.
Nombre de clase completo → | |
OpcionalPrefijoPaqueteNombreSimple | |
Prefijo de paquete opcional → | |
( Nombre simple '/' )* |
Descriptor de tipo
Utilizado por type_id_item
Un TypeDescriptor es la representación de cualquier tipo, incluidos primitivos, clases, matrices y void
. Consulte a continuación el significado de las distintas versiones.
Descriptor de tipo → | |
'V' | |
| | Descriptor de tipo de campo |
Descriptor de tipo de campo → | |
Descriptor de tipo de campo sin matriz | |
| | ( '[' * 1…255) Descriptor de tipo de campo sin matriz |
Descriptor de tipo de campo sin matriz → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' Nombre de clase completo ';' |
ShortyDescriptor
Utilizado por proto_id_item
Un ShortyDescriptor es la representación abreviada de un prototipo de método, incluidos los tipos de retorno y parámetros, excepto que no hay distinción entre varios tipos de referencia (clase o matriz). En cambio, todos los tipos de referencia están representados por un único carácter 'L'
.
ShortyDescriptor → | |
ShortyReturnType ( ShortyFieldType )* | |
ShortyReturnType → | |
'V' | |
| | Tipo de campo corto |
Tipo de campo corto → | |
'Z' | |
| | 'B' |
| | 'S' |
| | 'C' |
| | 'I' |
| | 'J' |
| | 'F' |
| | 'D' |
| | 'L' |
Semántica de TypeDescriptor
Este es el significado de cada una de las variantes de TypeDescriptor .
Sintaxis | Significado |
---|---|
V | void ; sólo válido para tipos de devolución |
z | boolean |
B | byte |
S | short |
C | char |
I | int |
j | long |
F | float |
D | double |
L totalmente/cualificado/Nombre ; | la clase fully.qualified.Name |
[ descriptor | matriz de descriptor , utilizable recursivamente para matrices de matrices, aunque no es válido tener más de 255 dimensiones. |
Artículos y estructuras relacionadas.
Esta sección incluye definiciones para cada uno de los elementos de nivel superior que pueden aparecer en un archivo .dex
.
elemento_encabezado
Aparece en la sección del encabezado.
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
magia | ubyte[8] = DEX_FILE_MAGIC | valor mágico. Consulte la discusión anterior en " DEX_FILE_MAGIC " para obtener más detalles. |
suma de control | uint | suma de comprobación adler32 del resto del archivo (todo menos magic y este campo); utilizado para detectar corrupción de archivos |
firma | ubyte[20] | Firma SHA-1 (hash) del resto del archivo (todo menos magic , checksum y este campo); Se utiliza para identificar archivos de forma única. |
tamaño del archivo | uint | tamaño de todo el archivo (incluido el encabezado), en bytes |
tamaño_encabezado | unidad = 0x70 | Tamaño del encabezado (esta sección completa), en bytes. Esto permite al menos una cantidad limitada de compatibilidad hacia adelante y hacia atrás sin invalidar el formato. |
endian_tag | uint=ENDIAN_CONSTANT | etiqueta de endianidad. Consulte la discusión anterior en " ENDIAN_CONSTANT y REVERSE_ENDIAN_CONSTANT " para obtener más detalles. |
tamaño_enlace | uint | tamaño de la sección del enlace, o 0 si este archivo no está vinculado estáticamente |
enlace_apagado | uint | desplazamiento desde el inicio del archivo hasta la sección del enlace, o 0 si link_size == 0 . El desplazamiento, si es distinto de cero, debe ser un desplazamiento en la sección link_data . El formato de los datos señalados no se especifica en este documento; Este campo de encabezado (y el anterior) se dejan como enlaces para que los utilicen las implementaciones en tiempo de ejecución. |
mapa_apagado | uint | desplazamiento desde el inicio del archivo hasta el elemento del mapa. El desplazamiento, que debe ser distinto de cero, debe ser un desplazamiento en la sección data y los datos deben estar en el formato especificado en " map_list " a continuación. |
tamaño_id_cadena | uint | recuento de cadenas en la lista de identificadores de cadenas |
string_ids_off | uint | desplazamiento desde el inicio del archivo hasta la lista de identificadores de cadenas, o 0 si string_ids_size == 0 (ciertamente, un caso extremo extraño). El desplazamiento, si es distinto de cero, debe ser hasta el inicio de la sección string_ids . |
tipo_ids_tamaño | uint | recuento de elementos en la lista de identificadores de tipo, como máximo 65535 |
tipo_ids_off | uint | desplazamiento desde el inicio del archivo hasta la lista de identificadores de tipo, o 0 si type_ids_size == 0 (ciertamente, un caso extremo extraño). El desplazamiento, si es distinto de cero, debe estar al inicio de la sección type_ids . |
tamaño_proto_ids | uint | recuento de elementos en la lista de identificadores del prototipo, como máximo 65535 |
proto_ids_off | uint | desplazamiento desde el inicio del archivo hasta la lista de identificadores de prototipo, o 0 si proto_ids_size == 0 (ciertamente, un caso extremo extraño). El desplazamiento, si es distinto de cero, debe ser hasta el inicio de la sección proto_ids . |
tamaño_id_campo | uint | recuento de elementos en la lista de identificadores de campo |
campo_ids_off | uint | desplazamiento desde el inicio del archivo hasta la lista de identificadores de campo, o 0 si field_ids_size == 0 . El desplazamiento, si es distinto de cero, debe llegar al inicio de la sección field_ids . |
método_ids_tamaño | uint | recuento de elementos en la lista de identificadores de métodos |
método_ids_off | uint | desplazamiento desde el inicio del archivo hasta la lista de identificadores de métodos, o 0 si method_ids_size == 0 . El desplazamiento, si es distinto de cero, debe ser hasta el inicio de la sección method_ids . |
tamaño_defs_clase | uint | recuento de elementos en la lista de definiciones de clases |
clase_defs_off | uint | desplazamiento desde el inicio del archivo hasta la lista de definiciones de clases, o 0 si class_defs_size == 0 (ciertamente, un caso extremo extraño). El desplazamiento, si es distinto de cero, debe ser hasta el inicio de la sección class_defs . |
tamaño de datos | uint | Tamaño de la sección data en bytes. Debe ser un múltiplo par de sizeof(uint). |
datos_apagados | uint | desplazamiento desde el inicio del archivo hasta el inicio de la sección data . |
lista_mapa
Aparece en la sección de datos.
Referenciado desde header_item
Alineación: 4 bytes
Esta es una lista de todo el contenido de un archivo, en orden. Contiene cierta redundancia con respecto a header_item
pero pretende ser una forma fácil de usar para iterar sobre un archivo completo. Un tipo determinado debe aparecer como máximo una vez en un mapa, pero no hay ninguna restricción sobre el orden en el que pueden aparecer los tipos, aparte de las restricciones implícitas en el resto del formato (por ejemplo, una sección header
debe aparecer primero, seguida de string_ids
sección, etcétera). Además, las entradas del mapa deben ordenarse por desplazamiento inicial y no deben superponerse.
Nombre | Formato | Descripción |
---|---|---|
tamaño | uint | tamaño de la lista, en entradas |
lista | elemento_mapa[tamaño] | elementos de la lista |
formato de elemento de mapa
Nombre | Formato | Descripción |
---|---|---|
tipo | corto | tipo de artículos; vea la tabla de abajo |
no usado | corto | (no usado) |
tamaño | uint | recuento del número de elementos que se encuentran en el desplazamiento indicado |
compensar | uint | desplazamiento desde el inicio del archivo hasta los elementos en cuestión |
Códigos de tipo
Tipo de artículo | Constante | Valor | Tamaño del elemento en bytes |
---|---|---|---|
elemento_encabezado | TYPE_HEADER_ITEM | 0x0000 | 0x70 |
elemento_id_cadena | TYPE_STRING_ID_ITEM | 0x0001 | 0x04 |
tipo_id_elemento | TYPE_TYPE_ID_ITEM | 0x0002 | 0x04 |
proto_id_item | TYPE_PROTO_ID_ITEM | 0x0003 | 0x0c |
elemento_id_campo | TYPE_FIELD_ID_ITEM | 0x0004 | 0x08 |
método_id_elemento | 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 |
método_handle_item | TYPE_METHOD_HANDLE_ITEM | 0x0008 | 0x08 |
lista_mapa | TYPE_MAP_LIST | 0x1000 | 4 + (tamaño del artículo * 12) |
lista_tipo | TYPE_TYPE_LIST | 0x1001 | 4 + (tamaño del artículo * 2) |
anotación_set_ref_list | TYPE_ANNOTATION_SET_REF_LIST | 0x1002 | 4 + (tamaño del artículo * 4) |
anotación_conjunto_item | TYPE_ANNOTATION_SET_ITEM | 0x1003 | 4 + (tamaño del artículo * 4) |
elemento_datos_clase | TYPE_CLASS_DATA_ITEM | 0x2000 | implícito; debe analizar |
elemento_código | TIPO_CÓDIGO_ITEM | 0x2001 | implícito; debe analizar |
elemento_datos_cadena | TYPE_STRING_DATA_ITEM | 0x2002 | implícito; debe analizar |
elemento_info_depuración | TYPE_DEBUG_INFO_ITEM | 0x2003 | implícito; debe analizar |
elemento_anotación | TYPE_ANNOTATION_ITEM | 0x2004 | implícito; debe analizar |
elemento_matriz_codificada | TYPE_ENCODED_ARRAY_ITEM | 0x2005 | implícito; debe analizar |
elemento_directorio_anotaciones | TYPE_ANNOTATION_DIRECTORY_ITEM | 0x2006 | implícito; debe analizar |
elemento_datos_clase_api_oculto | TYPE_HIDDENAPI_CLASS_DATA_ITEM | 0xF000 | implícito; debe analizar |
elemento_id_cadena
Aparece en la sección string_ids
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
string_data_off | uint | desplazamiento desde el inicio del archivo hasta los datos de cadena para este elemento. El desplazamiento debe ser una ubicación en la sección data y los datos deben estar en el formato especificado en " string_data_item " a continuación. No hay ningún requisito de alineación para el desplazamiento. |
elemento_datos_cadena
Aparece en la sección de datos.
Alineación: ninguna (alineada por bytes)
Nombre | Formato | Descripción |
---|---|---|
utf16_tamaño | uleb128 | tamaño de esta cadena, en unidades de código UTF-16 (que es la "longitud de la cadena" en muchos sistemas). Es decir, esta es la longitud decodificada de la cadena. (La longitud codificada está implícita en la posición del byte 0 ). |
datos | ubyte[] | una serie de unidades de código MUTF-8 (también conocidas como octetos, también conocidos como bytes) seguidas de un byte de valor 0 . Consulte "Codificación MUTF-8 (UTF-8 modificada)" más arriba para obtener detalles y discusión sobre el formato de datos. Nota: Es aceptable tener una cadena que incluya (la forma codificada de) unidades de código sustituto UTF-16 (es decir, |
tipo_id_elemento
Aparece en la sección type_ids
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
descriptor_idx | uint | indexe en la lista string_ids para la cadena descriptiva de este tipo. La cadena debe ajustarse a la sintaxis de TypeDescriptor , definida anteriormente. |
proto_id_item
Aparece en la sección proto_ids
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
shorty_idx | uint | indexe en la lista string_ids para la cadena descriptiva de formato corto de este prototipo. La cadena debe ajustarse a la sintaxis de ShortyDescriptor , definida anteriormente, y debe corresponder al tipo de retorno y los parámetros de este elemento. |
return_type_idx | uint | indexar en la lista type_ids para el tipo de retorno de este prototipo |
parámetros_off | uint | desplazamiento desde el inicio del archivo hasta la lista de tipos de parámetros para este prototipo, o 0 si este prototipo no tiene parámetros. Este desplazamiento, si es distinto de cero, debe estar en la sección data y los datos deben estar en el formato especificado en "type_list" a continuación. Además, no debe haber ninguna referencia al tipo void en la lista. |
elemento_id_campo
Aparece en la sección field_ids
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
clase_idx | corto | indexe en la lista type_ids para el definidor de este campo. Debe ser un tipo de clase y no una matriz o un tipo primitivo. |
tipo_idx | corto | indexar en la lista type_ids para el tipo de este campo |
nombre_idx | uint | indexe en la lista string_ids para el nombre de este campo. La cadena debe ajustarse a la sintaxis de MemberName , definida anteriormente. |
método_id_elemento
Aparece en la sección Method_ids
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
clase_idx | corto | indexe en la lista type_ids para el definidor de este método. Debe ser un tipo de clase o matriz, y no un tipo primitivo. |
proto_idx | corto | indexar en la lista proto_ids para el prototipo de este método |
nombre_idx | uint | indexe en la lista string_ids el nombre de este método. La cadena debe ajustarse a la sintaxis de MemberName , definida anteriormente. |
class_def_item
Aparece en la sección class_defs
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
clase_idx | uint | indexar en la lista type_ids para esta clase. Debe ser un tipo de clase y no una matriz o un tipo primitivo. |
banderas_acceso | uint | banderas de acceso para la clase ( public , final , etc.). Consulte "Definiciones access_flags " para obtener más detalles. |
superclase_idx | uint | indexe en la lista type_ids para la superclase, o el valor constante NO_INDEX si esta clase no tiene superclase (es decir, es una clase raíz como Object ). Si está presente, debe ser un tipo de clase y no una matriz o un tipo primitivo. |
interfaces_off | uint | desplazamiento desde el inicio del archivo hasta la lista de interfaces, o 0 si no hay ninguna. Este desplazamiento debe estar en la sección data , y los datos deben estar en el formato especificado en " type_list " a continuación. Cada uno de los elementos de la lista debe ser un tipo de clase (no una matriz o un tipo primitivo) y no debe haber duplicados. |
idx_archivo_fuente | uint | indexe en la lista string_ids el nombre del archivo que contiene la fuente original de (al menos la mayor parte) de esta clase, o el valor especial NO_INDEX para representar la falta de esta información. El debug_info_item de cualquier método determinado puede anular este archivo fuente, pero la expectativa es que la mayoría de las clases solo provengan de un archivo fuente. |
anotaciones_off | uint | desplazamiento desde el inicio del archivo hasta la estructura de anotaciones para esta clase, o 0 si no hay anotaciones en esta clase. Este desplazamiento, si es distinto de cero, debe estar en la sección data , y los datos deben estar en el formato especificado en " annotations_directory_item " a continuación, con todos los elementos haciendo referencia a esta clase como definidor. |
clase_datos_apagado | uint | desplazamiento desde el inicio del archivo hasta los datos de clase asociados para este elemento, o 0 si no hay datos de clase para esta clase. (Este puede ser el caso, por ejemplo, si esta clase es una interfaz de marcador). El desplazamiento, si es distinto de cero, debe estar en la sección data , y los datos deben estar en el formato especificado en " class_data_item " a continuación. con todos los elementos que se refieren a esta clase como definidor. |
valores_estáticos_apagados | uint | desplazamiento desde el inicio del archivo hasta la lista de valores iniciales para campos static , o 0 si no hay ninguno (y todos los campos static deben inicializarse con 0 o null ). Este desplazamiento debe estar en la sección data , y los datos deben estar en el formato especificado en " encoded_array_item " a continuación. El tamaño de la matriz no debe ser mayor que el número de campos static declarados por esta clase, y los elementos corresponden a los campos static en el mismo orden declarado en la field_list correspondiente. El tipo de cada elemento de la matriz debe coincidir con el tipo declarado de su campo correspondiente. Si hay menos elementos en la matriz que campos static , entonces los campos sobrantes se inicializan con un 0 o null apropiado para el tipo. |
call_site_id_item
Aparece en la sección call_site_ids
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
sitio_llamada_apagado | uint | desplazamiento desde el inicio del archivo para llamar a la definición del sitio. El desplazamiento debe estar en la sección de datos y los datos deben estar en el formato especificado en "call_site_item" a continuación. |
elemento_sitio_llamada
Aparece en la sección de datos.
Alineación: ninguna (byte alineado)
call_site_item es un encoded_array_item cuyos elementos corresponden a los argumentos proporcionados a un método de enlace de arranque. Los primeros tres argumentos son:
- Un identificador de método que representa el método del vinculador de arranque (VALUE_METHOD_HANDLE).
- Un nombre de método que el vinculador de arranque debe resolver (VALUE_STRING).
- Un tipo de método correspondiente al tipo del nombre del método que se va a resolver (VALUE_METHOD_TYPE).
Cualquier argumento adicional son valores constantes pasados al método del vinculador de arranque. Estos argumentos se pasan en orden y sin ninguna conversión de tipo.
El identificador del método que representa el método del vinculador de arranque debe tener un tipo de retorno java.lang.invoke.CallSite
. Los primeros tres tipos de parámetros son:
-
java.lang.invoke.Lookup
-
java.lang.String
-
java.lang.invoke.MethodType
Los tipos de parámetros de cualquier argumento adicional se determinan a partir de sus valores constantes.
método_handle_item
Aparece en la sección método_handles
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
método_handle_type | corto | tipo de identificador del método; vea la tabla de abajo |
no usado | corto | (no usado) |
campo_o_método_id | corto | ID de campo o método dependiendo de si el tipo de identificador del método es un descriptor de acceso o un invocador de método |
no usado | corto | (no usado) |
Códigos de tipo de identificador de método
Constante | Valor | Descripción |
---|---|---|
METHOD_HANDLE_TYPE_STATIC_PUT | 0x00 | El identificador del método es un definidor de campo estático (accesor) |
METHOD_HANDLE_TYPE_STATIC_GET | 0x01 | El identificador del método es un captador de campo estático (accesor) |
METHOD_HANDLE_TYPE_INSTANCE_PUT | 0x02 | El identificador del método es un definidor de campo de instancia (accesor) |
METHOD_HANDLE_TYPE_INSTANCE_GET | 0x03 | El identificador del método es un captador de campo de instancia (accesor) |
METHOD_HANDLE_TYPE_INVOKE_STATIC | 0x04 | El identificador de método es un invocador de método estático |
METHOD_HANDLE_TYPE_INVOKE_INSTANCE | 0x05 | El identificador de método es un invocador de método de instancia |
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR | 0x06 | El identificador del método es un invocador del método constructor. |
METHOD_HANDLE_TYPE_INVOKE_DIRECT | 0x07 | Method Handle es un método directo Invocador |
Métod_handle_type_invoke_interface | 0x08 | Method Handle es un método de interfaz invok |
class_data_item
Referenciado desde class_def_item
Aparece en la sección de datos
Alineación: ninguno (byte alineado)
Nombre | Formato | Descripción |
---|---|---|
static_fields_size | ULEB128 | el número de campos estáticos definidos en este artículo |
instance_fields_size | ULEB128 | el número de campos de instancia definidos en este elemento |
direct_methods_size | ULEB128 | el número de métodos directos definidos en este elemento |
virtual_methods_size | ULEB128 | El número de métodos virtuales definidos en este elemento |
static_fields | Encoded_field [static_fields_size] | Los campos estáticos definidos, representados como una secuencia de elementos codificados. Los campos deben ser ordenados por field_idx en orden creciente. |
instance_fields | Encoded_field [instancia_fields_size] | Los campos de instancia definidos, representados como una secuencia de elementos codificados. Los campos deben ser ordenados por field_idx en orden creciente. |
Direct_methods | Encoded_method [direct_methods_size] | Los métodos directos definidos (cualquiera de static , private o constructor), representados como una secuencia de elementos codificados. Los métodos deben ser ordenados por method_idx en orden creciente. |
virtual_methods | encoded_method [virtual_methods_size] | Los métodos virtuales definidos (ninguno de static , private o constructores), representados como una secuencia de elementos codificados. Esta lista no debe incluir métodos heredados a menos que la clase anule la clase que representa este elemento. Los métodos deben ser ordenados por method_idx en orden creciente. El method_idx de un método virtual no debe ser el mismo que cualquier método directo. |
NOTA: Todos los instancias field_id
y method_id
de los Elementos deben referirse a la misma clase de definición.
formato de code_field
Nombre | Formato | Descripción |
---|---|---|
campo_idx_diff | ULEB128 | Index en la lista field_ids para la identidad de este campo (incluye el nombre y el descriptor), representada como una diferencia con el índice del elemento anterior en la lista. El índice del primer elemento en una lista se representa directamente. |
banderas_acceso | ULEB128 | Acceda a banderas para el campo ( public , final , etc.). Consulte "Definiciones access_flags " para más detalles. |
formato de method
Nombre | Formato | Descripción |
---|---|---|
métod_idx_diff | ULEB128 | Index en la lista method_ids para la identidad de este método (incluye el nombre y el descriptor), representada como una diferencia con el índice del elemento anterior en la lista. El índice del primer elemento en una lista se representa directamente. |
banderas_acceso | ULEB128 | Acceso a las banderas para el método ( public , final , etc.). Consulte "Definiciones access_flags " para más detalles. |
Code_off | ULEB128 | Compensación desde el inicio del archivo a la estructura del código para este método, o 0 si este método es abstract o native . El desplazamiento debe estar en una ubicación en la sección data . El formato de los datos se especifica por " code_item " a continuación. |
type_list
Referenciado desde class_def_item y proto_id_item
Aparece en la sección de datos
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
tamaño | uint | tamaño de la lista, en entradas |
lista | type_item [tamaño] | Elementos de la lista |
formato type_item
Nombre | Formato | Descripción |
---|---|---|
type_idx | corto | índice en la lista type_ids |
Code_Item
Referenciado desde encoded_method
Aparece en la sección de datos
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
registros_size | corto | el número de registros utilizados por este código |
Ins_size | corto | el número de palabras de argumentos entrantes al método para el que este código es para |
outs_size | corto | El número de palabras de espacio de argumento saliente requerido por este código para la invocación del método |
intenta_size | corto | El número de try_item s para esta instancia. Si no es cero, entonces estos aparecen como la matriz tries justo después de los insns en este caso. |
debug_info_off | uint | Compensación desde el inicio del archivo hasta la secuencia de información de depuración (números de línea + información variable local) para este código, o 0 si simplemente no hay información. El desplazamiento, si no es cero, debe estar en una ubicación en la sección data . El formato de los datos se especifica mediante " debug_info_item " a continuación. |
insns_size | uint | Tamaño de la lista de instrucciones, en unidades de código de 16 bits |
insignia | USHORT [INSNS_SIZE] | Matriz real de Bytecode. El formato de código en una matriz insns se especifica por el documento complementario Dalvik bytecode . Tenga en cuenta que aunque esto se define como una variedad de ushort , hay algunas estructuras internas que prefieren la alineación de cuatro bytes. Además, si esto se encuentra en un archivo endian-swapped, entonces el intercambio solo se realiza en instancias individuales ushort y no en las estructuras internas más grandes. |
relleno | Ushort (opcional) = 0 | Dos bytes de relleno para hacer tries de cuatro bytes alineados. Este elemento solo está presente si tries_size no es cero e insns_size es impar. |
intentos | try_item [inties_size] (opcional) | La matriz que indica en qué parte se captura las excepciones de código y cómo manejarlas. Los elementos de la matriz no deben superarse en el rango y en orden de dirección baja a alta. Este elemento solo está presente si tries_size no es cero. |
manejadores | Encoded_catch_handler_list (opcional) | Bytes que representan una lista de listas de tipos de captura y direcciones de controladores asociados. Cada try_item tiene una compensación de bytes en esta estructura. Este elemento solo está presente si tries_size no es cero. |
Formato de try_item
Nombre | Formato | Descripción |
---|---|---|
start_addr | uint | Inicie la dirección del bloque del código cubierto por esta entrada. La dirección es un recuento de unidades de código de 16 bits al inicio de la primera instrucción cubierta. |
Insn_Count | corto | Número de unidades de código de 16 bits cubiertas por esta entrada. La última unidad de código cubierta (inclusive) es start_addr + insn_count - 1 . |
Handler_off | corto | Compensación en bytes desde el inicio del encoded_catch_hander_list asociado a la encoded_catch_handler para esta entrada. Esto debe ser un desplazamiento al inicio de un encoded_catch_handler . |
Encoded_catch_handler_list format
Nombre | Formato | Descripción |
---|---|---|
tamaño | ULEB128 | tamaño de esta lista, en entradas |
lista | Encoded_catch_handler [Handlers_Size] | Lista real de listas de controladores, representadas directamente (no como compensaciones) y concatenadas secuencialmente |
Formato de encodeD_Catch_Handler
Nombre | Formato | Descripción |
---|---|---|
tamaño | Sleb128 | Número de tipos de captura en esta lista. Si no es positivo, entonces este es el negativo del número de tipos de captura, y las capturas son seguidas por un controlador de captura. Por ejemplo: un size de 0 significa que hay una captura, pero no hay capturas explícitamente escrita. Un size de 2 significa que hay dos capturas escrita explícitamente y no hay nada. Y un size de -1 significa que hay una captura escrita junto con una trampa. |
manejadores | ENCODED_TYPE_ADDR_PAIR [ABS (tamaño)] | flujo de elementos codificados abs(size) , uno para cada tipo de atrapado, en el orden de que los tipos deben probarse. |
Catch_all_addr | ULEB128 (opcional) | Dirección de Bytecode del controlador de todo. Este elemento solo está presente si size no es positivo. |
Encoded_type_addr_pair format
Nombre | Formato | Descripción |
---|---|---|
type_idx | ULEB128 | índice en la lista type_ids para el tipo de excepción para atrapar |
dirección | ULEB128 | Dirección de Bytecode del controlador de excepciones asociado |
debug_info_item
Referenciado desde code_item
Aparece en la sección de datos
Alineación: ninguno (byte alineado)
Cada debug_info_item
define una máquina de estado codificada por bytes inspirada en DWARF3 que, cuando se interpreta, emite la tabla de posiciones y (potencialmente) la información variable local para un code_item
. La secuencia comienza con un encabezado de longitud variable (la longitud de la cual depende del número de parámetros del método), es seguida por los bytes de la máquina de estado y termina con un byte DBG_END_SEQUENCE
.
La máquina de estado consta de cinco registros. El registro address
representa el desplazamiento de instrucciones en el insns_item
asociado en unidades de código de 16 bits. El registro de address
comienza a 0
al comienzo de cada secuencia debug_info
y solo debe aumentar monotónicamente. El registro line
representa qué número de línea de origen debe estar asociado con la siguiente entrada de tabla de posiciones emitida por la máquina de estado. Se inicializa en el encabezado de secuencia, y puede cambiar en direcciones positivas o negativas, pero nunca debe ser inferior a 1
. El registro source_file
representa el archivo de origen al que se refieren las entradas del número de línea. Se inicializa al valor de source_file_idx
en class_def_item
. Las otras dos variables, prologue_end
y epilogue_begin
, son banderas booleanas (inicializadas a false
) que indican si la siguiente posición emitida debe considerarse un prólogo o epílogo del método. La máquina de estado también debe rastrear el nombre y el tipo de la última variable local en vivo en cada registro para el código DBG_RESTART_LOCAL
.
El encabezado es el siguiente:
Nombre | Formato | Descripción |
---|---|---|
inicio_linea | ULEB128 | El valor inicial para el registro de line de la máquina de estado. No representa una entrada de posiciones reales. |
parámetros_size | ULEB128 | El número de nombres de parámetros que están codificados. Debe haber un parámetro por método, excluyendo un método de instancia this , si lo hay. |
parámetro_names | ULEB128P1 [parámetros_size] | Índice de cadena del nombre del parámetro del método. Un valor codificado de NO_INDEX indica que no hay nombre disponible para el parámetro asociado. El descriptor de tipo y la firma están implícitos en el descriptor y la firma del método. |
Los valores del código de byte son los siguientes:
Nombre | Valor | Formato | Argumentos | Descripción |
---|---|---|---|---|
Dbg_end_sequence | 0x00 | (ninguno) | Termina una secuencia de información de depuración para un code_item | |
Dbg_advance_pc | 0x01 | ULEB128 ADDR_DIFF | addr_diff : Cantidad para agregar al registro de la dirección | Avanza el registro de direcciones sin emitir una entrada de posiciones |
Dbg_advance_line | 0x02 | SLEB128 LINE_DIFF | line_diff : cantidad de registro de línea de cambio por | Avanza el registro de línea sin emitir una entrada de posiciones |
Dbg_start_local | 0x03 | ULEB128 Registro_num ULEB128P1 name_idx ULEB128P1 type_idx | register_num : Registro que contenga localname_idx : índice de cadena del nombretype_idx : índice de tipo del tipo | Presenta una variable local en la dirección actual. name_idx o type_idx puede ser NO_INDEX para indicar que ese valor es desconocido. |
Dbg_start_local_extended | 0x04 | ULEB128 Registro_num ULEB128P1 name_idx ULEB128P1 type_idx ULEB128P1 SIG_IDX | register_num : Registro que contenga localname_idx : índice de cadena del nombretype_idx : índice de tipo del tiposig_idx : índice de cadena de la firma de tipo | Introduce un local con una firma de tipo en la dirección actual. Cualquiera de name_idx , type_idx o sig_idx puede ser NO_INDEX para indicar que ese valor es desconocido. (Sin embargo, si sig_idx es -1 , los mismos datos podrían representarse de manera más eficiente utilizando el Código OPT DBG_START_LOCAL ). Nota: Consulte la discusión en " |
Dbg_end_local | 0x05 | ULEB128 Registro_num | register_num : Registro que contenía local | marca una variable local actualmente viva como fuera del alcance en la dirección actual |
DBG_RESTART_LOCAL | 0x06 | ULEB128 Registro_num | register_num : Regístrese para reiniciar | reintroduce una variable local en la dirección actual. El nombre y el tipo son los mismos que el último local que estaba en vivo en el registro especificado. |
Dbg_set_prologue_end | 0x07 | (ninguno) | Establece el registro de la máquina de estado prologue_end , lo que indica que la siguiente entrada de posición que se agrega debe considerarse el final de un prólogo del método (un lugar apropiado para un punto de interrupción del método). El registro prologue_end se borra por cualquier código de operación especial ( >= 0x0a ). | |
DBG_SET_EPILOGO_BEGIN | 0x08 | (ninguno) | Establece el Registro de máquina de Estado epilogue_begin , lo que indica que la siguiente entrada de posición que se agrega debe considerarse el comienzo de un Método Epílogo (un lugar apropiado para suspender la ejecución antes de la salida del método). El registro epilogue_begin se borra por cualquier código de operación especial ( >= 0x0a ). | |
Dbg_set_file | 0x09 | ULEB128P1 name_idx | name_idx : Índice de cadena del nombre de archivo de origen; NO_INDEX si se desconoce | indica que todas las entradas de número de línea posterior hacen referencia a este nombre de archivo de origen, en lugar del nombre predeterminado especificado en code_item |
Códigos de operación especiales | 0x0a ... 0xff | (ninguno) | Avanza los registros de line y address , emite una entrada de posición y borra prologue_end y epilogue_begin . Consulte la descripción a continuación. |
Códigos de operación especiales
Los códigos de operación con valores entre 0x0a
y 0xff
(inclusive) mueven los registros de line
y address
por una pequeña cantidad y luego emiten una nueva entrada de tabla de posición. La fórmula para los incrementos es el siguiente:
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)
anotaciones_directory_item
Referenciado desde class_def_item
Aparece en la sección de datos
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
class_annotations_off | uint | Compensación desde el inicio del archivo hasta las anotaciones realizadas directamente en la clase, o 0 si la clase no tiene anotaciones directas. El desplazamiento, si no es cero, debe estar en una ubicación en la sección data . El formato de los datos se especifica mediante " annotation_set_item " a continuación. |
campos_size | uint | recuento de campos anotados por este artículo |
anotado_methods_size | uint | recuento de métodos anotados por este artículo |
anotado_parameters_size | uint | Cuenta de listas de parámetros de método anotadas por este elemento |
Field_annotations | Field_annotation [Fields_Size] (opcional) | Lista de anotaciones de campo asociadas. Los elementos de la lista deben clasificarse en orden creciente, por field_idx . |
Method_annotations | Method_annotation [Methods_Size] (opcional) | Lista de anotaciones de métodos asociados. Los elementos de la lista deben clasificarse en orden creciente, por method_idx . |
Parameter_Annotations | parameter_annotation [parámetros_size] (opcional) | Lista de anotaciones de parámetros de método asociado. Los elementos de la lista deben clasificarse en orden creciente, por method_idx . |
NOTA: Todos los instancias field_id
y method_id
de los Elementos deben referirse a la misma clase de definición.
formato de campo_annotación
Nombre | Formato | Descripción |
---|---|---|
campo_idx | uint | índice en la lista field_ids para la identidad del campo que se anota |
anotaciones_off | uint | Compensación desde el inicio del archivo hasta la lista de anotaciones para el campo. El desplazamiento debe estar en una ubicación en la sección data . El formato de los datos se especifica mediante " annotation_set_item " a continuación. |
Method_annotation Format
Nombre | Formato | Descripción |
---|---|---|
Method_idx | uint | índice en la lista method_ids para la identidad del método que se anota |
anotaciones_off | uint | Compensación desde el inicio del archivo hasta la lista de anotaciones para el método. El desplazamiento debe estar en una ubicación en la sección data . El formato de los datos se especifica mediante " annotation_set_item " a continuación. |
Parameter_Annotation Formato
Nombre | Formato | Descripción |
---|---|---|
Method_idx | uint | índice en la lista method_ids para la identidad del método cuyos parámetros se están anotando |
anotaciones_off | uint | Compensación desde el inicio del archivo a la lista de anotaciones para los parámetros del método. El desplazamiento debe estar en una ubicación en la sección data . El formato de los datos se especifica por " annotation_set_ref_list " a continuación. |
anotación_set_ref_list
Referenciado desde parameter_annotations_item
Aparece en la sección de datos
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
tamaño | uint | tamaño de la lista, en entradas |
lista | anotación_set_ref_item [tamaño] | Elementos de la lista |
Annotation_set_ref_item format
Nombre | Formato | Descripción |
---|---|---|
anotaciones_off | uint | Compensación desde el inicio del archivo al conjunto de anotaciones referenciado o 0 si no hay anotaciones para este elemento. El desplazamiento, si no es cero, debe estar en una ubicación en la sección data . El formato de los datos se especifica mediante " annotation_set_item " a continuación. |
anotación_set_item
Referenciado desde annotations_directory_item, field_annotations_item, método_annotations_item y annotation_set_ref_item
Aparece en la sección de datos
Alineación: 4 bytes
Nombre | Formato | Descripción |
---|---|---|
tamaño | uint | tamaño del conjunto, en entradas |
entradas | anotación_off_item [tamaño] | elementos del conjunto. Los elementos deben ordenarse en orden creciente, por type_idx . |
Annotation_off_item format
Nombre | Formato | Descripción |
---|---|---|
anotación_off | uint | Compensación desde el inicio del archivo hasta una anotación. El desplazamiento debe estar en una ubicación en la sección data , y el formato de los datos en esa ubicación se especifica mediante " annotation_item " a continuación. |
anotación_item
Referenciado de annotation_set_item
Aparece en la sección de datos
Alineación: ninguno (byte alineado)
Nombre | Formato | Descripción |
---|---|---|
visibilidad | usbyte | Visibilidad prevista de esta anotación (ver más abajo) |
anotación | encoded_annotation | Contenido de anotación codificada, en el formato descrito por "formato encoded_annotation " en "codificación encoded_value " anteriormente. |
Valores de visibilidad
Estas son las opciones para el campo visibility
en un annotation_item
:
Nombre | Valor | Descripción |
---|---|---|
Visibilidad_build | 0x00 | destinado solo a ser visible en el tiempo de compilación (por ejemplo, durante la compilación de otro código) |
Visibilidad_runtime | 0x01 | destinado a visible en tiempo de ejecución |
Visibilidad_system | 0x02 | destinado a visible en tiempo de ejecución, pero solo al sistema subyacente (y no al código de usuario regular) |
encoded_array_item
Referenciado desde class_def_item
Aparece en la sección de datos
Alineación: ninguno (byte alineado)
Nombre | Formato | Descripción |
---|---|---|
valor | encoded_array | bytes que representan el valor de matriz codificado, en el formato especificado por "formato encoded_array " en " encoded_value " arriba "anterior. |
Hiddenapi_class_data_item
Esta sección contiene datos sobre las interfaces restringidas utilizadas por cada clase.
Nota: La función API oculta se introdujo en Android 10.0 y solo se aplica a los archivos dex de clases Dex en la ruta de clase de arranque. La lista de banderas descritas a continuación puede extenderse en las versiones futuras de Android. Para obtener más información, consulte Restricciones sobre interfaces que no son SDK .
Nombre | Formato | Descripción |
---|---|---|
tamaño | uint | Tamaño total de la sección |
compensaciones | unidad[] | Matriz de compensaciones indexadas por class_idx . Una entrada de matriz cero en index class_idx significa que no hay datos para este class_idx , o todos los indicadores de API ocultos son cero. De lo contrario, la entrada de la matriz no es cero y contiene un desplazamiento desde el comienzo de la sección hasta una matriz de banderas API ocultas para este class_idx . |
banderas | ULEB128 [] | Matrices concatenados de banderas API ocultas para cada clase. Los posibles valores de bandera se describen en la tabla a continuación. Las banderas están codificadas en el mismo orden que los campos y los métodos están codificados en los datos de clase. |
Tipos de bandera de restricción:
Nombre | Valor | Descripción |
---|---|---|
lista blanca | 0 | Interfaces que se pueden usar libremente y son compatibles como parte del índice de paquetes Android Framework de Android oficialmente documentado. |
lista gris | 1 | Interfaces que no son SDK que se pueden usar independientemente del nivel de API objetivo de la aplicación. |
lista negra | 2 | Interfaces que no son SDK que no se pueden utilizar independientemente del nivel de API objetivo de la aplicación. Acceder a una de estas interfaces provoca un error de tiempo de ejecución . |
Greylist -max -o | 3 | Interfaces que no son SDK que se pueden usar para Android 8.x y debajo a menos que estén restringidas. |
Greylist -max -P | 4 | Interfaces que no son SDK que se pueden usar para Android 9.x a menos que estén restringidas. |
Greylist -max -q | 5 | Interfaces que no son SDK que se pueden usar para Android 10.x a menos que estén restringidas. |
greylist -max -r | 6 | Interfaces que no son SDK que se pueden usar para Android 11.x a menos que estén restringidas. |
Anotaciones del sistema
Las anotaciones del sistema se utilizan para representar varias piezas de información reflexiva sobre clases (y métodos y campos). Esta información generalmente solo se accede indirectamente por el código del cliente (no sistemas).
Las anotaciones del sistema se representan en archivos .dex
como anotaciones con visibilidad establecida en VISIBILITY_SYSTEM
.
dalvik.annotation.annotationdefault
Aparece en métodos en interfaces de anotación
Se adjunta una anotación AnnotationDefault
a cada interfaz de anotación que desea indicar enlaces predeterminados.
Nombre | Formato | Descripción |
---|---|---|
valor | Anotación | Los enlaces predeterminados para esta anotación, representados como una anotación de este tipo. La anotación no necesita incluir todos los nombres definidos por la anotación; Los nombres faltantes simplemente no tienen valores predeterminados. |
dalvik.Annotation.ClosingClass
Aparece en clases
Una anotación EnclosingClass
se adjunta a cada clase que se define como un miembro de otra clase, per se, o es anónimo pero no se define dentro de un cuerpo de método (por ejemplo, una clase interna sintética). Cada clase que tiene esta anotación también debe tener una anotación InnerClass
. Además, una clase no debe tener una anotación EnclosingClass
y una anotación EnclosingMethod
.
Nombre | Formato | Descripción |
---|---|---|
valor | Clase | la clase que alcanza más estrechamente esta clase |
dalvik.annotation.EntlosingMethod
Aparece en clases
Se une una anotación EnclosingMethod
a cada clase que se define dentro de un cuerpo de método. Cada clase que tiene esta anotación también debe tener una anotación InnerClass
. Además, una clase no debe tener una anotación EnclosingClass
y una anotación EnclosingMethod
.
Nombre | Formato | Descripción |
---|---|---|
valor | Método | El método que alcanza más estrechamente esta clase |
dalvik.annotation.innerClass
Aparece en clases
Se adjunta una anotación InnerClass
a cada clase que se define en el alcance léxico de la definición de otra clase. Cualquier clase que tenga esta anotación también debe tener una anotación EnclosingClass
o una anotación EnclosingMethod
.
Nombre | Formato | Descripción |
---|---|---|
nombre | Cadena | El nombre simple declarado originalmente de esta clase (sin incluir ningún prefijo de paquete). Si esta clase es anónima, entonces el nombre es null . |
Accessflags | En t | Los indicadores de acceso declarados originalmente de la clase (que pueden diferir de los indicadores efectivos debido a un desajuste entre los modelos de ejecución del lenguaje de origen y la máquina virtual de destino) |
dalvik.annotation.memblasses
Aparece en clases
Una anotación MemberClasses
se adjunta a cada clase que declara clases de miembros. (Una clase de miembro es una clase interna directa que tiene un nombre).
Nombre | Formato | Descripción |
---|---|---|
valor | Clase[] | matriz de las clases de miembros |
dalvik.annotation.metodparameters
Aparece en los métodos
Nota: Esta anotación se agregó después de Android 7.1. Su presencia en versiones anteriores de Android será ignorada.
Una anotación MethodParameters
es opcional y puede usarse para proporcionar metadatos de parámetros, como nombres de parámetros y modificadores.
La anotación se puede omitir desde un método o constructor de forma segura cuando los metadatos del parámetro no son necesarios en tiempo de ejecución. java.lang.reflect.Parameter.isNamePresent()
se puede usar para verificar si los metadatos están presentes para un parámetro, y los métodos de reflexión asociados como java.lang.reflect.Parameter.getName()
recurrirán al comportamiento predeterminado en tiempo de ejecución Si la información no está presente.
Al incluir metadatos de parámetros, los compiladores deben incluir información para clases generadas como Enums, ya que los metadatos del parámetro incluyen si un parámetro es sintético o exigido.
Una anotación MethodParameters
describe solo parámetros de método individual. Por lo tanto, los compiladores pueden omitir la anotación por completo para constructores y métodos que no tienen parámetros, por el tamaño del tamaño y la eficiencia de tiempo de ejecución.
Las matrices documentadas a continuación deben ser del mismo tamaño que para la estructura method_id_item
Dex asociada con el método, de lo contrario, se lanzará un java.lang.reflect.MalformedParametersException
en tiempo de ejecución.
Eso es: method_id_item.proto_idx
-> proto_id_item.parameters_off
-> type_list.size
debe ser lo mismo que names().length
y accessFlags().length
.
Debido a que MethodParameters
describe todos los parámetros del método formal, incluso aquellos que no se declaran explícita o implícitamente en el código fuente, el tamaño de las matrices puede diferir de la firma u otra información de metadatos que se basa solo en los parámetros explícitos declarados en el código fuente. MethodParameters
tampoco incluirá ninguna información sobre los parámetros del receptor de anotación de tipo que no existen en la firma del método real.
Nombre | Formato | Descripción |
---|---|---|
nombres | Cadena[] | Los nombres de los parámetros formales para el método asociado. La matriz no debe ser nula, pero debe estar vacía si no hay parámetros formales. Un valor en la matriz debe ser nulo si el parámetro formal con ese índice no tiene nombre. Si las cadenas de nombres de parámetros están vacías o contienen '.', ';', '[' O '/', entonces se lanzará un java.lang.reflect.MalformedParametersException en tiempo de ejecución. |
Accessflags | En t[] | Los indicadores de acceso de los parámetros formales para el método asociado. La matriz no debe ser nula, pero debe estar vacía si no hay parámetros formales. El valor es una máscara de bits con los siguientes valores:
java.lang.reflect.MalformedParametersException se lanzará en tiempo de ejecución. |
Dalvik.annotation. Signature
Aparece en clases, campos y métodos
Se adjunta una anotación Signature
a cada clase, campo o método que se define en términos de un tipo más complicado que el representable por un type_id_item
. El formato .dex
no define el formato para firmas; Simplemente está destinado a poder representar cualquier firma que requiera un lenguaje fuente para la implementación exitosa de la semántica de ese lenguaje. Como tal, las firmas generalmente no se analizan (o verifican) mediante implementaciones de máquina virtual. Las firmas simplemente se transmiten a API y herramientas de nivel superior (como debuggers). Cualquier uso de una firma, por lo tanto, debe escribirse para no hacer suposiciones sobre solo recibir firmas válidas, explícitamente protegerse contra la posibilidad de encontrar una firma sintácticamente inválida.
Debido a que las cadenas de firma tienden a tener mucho contenido duplicado, una anotación Signature
se define como una variedad de cadenas, donde los elementos duplicados se refieren naturalmente a los mismos datos subyacentes, y la firma se considera la concatenación de todas las cadenas en la matriz . No hay reglas sobre cómo separar una firma en cuerdas separadas; Eso depende completamente de las herramientas que generan archivos .dex
.
Nombre | Formato | Descripción |
---|---|---|
valor | Cadena[] | La firma de esta clase o miembro, como una variedad de cuerdas que se concatenarán juntos |
dalvik.annotation.throws
Aparece en los métodos
Se adjunta una anotación Throws
a cada método que se declara para lanzar uno o más tipos de excepción.
Nombre | Formato | Descripción |
---|---|---|
valor | Clase[] | la variedad de tipos de excepción lanzados |