Formato executável Dalvik

Este documento descreve o layout e o conteúdo dos arquivos .dex, que são usados para armazenar um conjunto de definições de classe e os dados adjuntos associados.

Guia de tipos

Nome Descrição
byte Int de 8 bits assinado
ubyte Int de 8 bits sem assinatura
short Int assinado de 16 bits, little-endian
ushort Int não assinado de 16 bits, little-endian
int Int assinado de 32 bits, little-endian
uint Int sem sinal de 32 bits, little-endian
long Int assinado de 64 bits, little-endian
ulong Int não assinado de 64 bits, little-endian
sleb128 LEB128 assinado, comprimento variável (consulte abaixo)
uleb128 LEB128 não assinado, de comprimento variável (consulte abaixo)
uleb128p1 LEB128 não assinado mais 1, comprimento variável (consulte abaixo)

LEB128

LEB128 ("Little-Endian Base 128") é uma codificação de comprimento variável para quantidades de números inteiros assinadas ou não assinadas arbitrárias. O formato foi emprestado da especificação DWARF3. Em um arquivo .dex, o LEB128 é usado apenas para codificar quantidades de 32 bits.

Cada valor codificado LEB128 consiste em um a cinco bytes, que juntos representam um único valor de 32 bits. Cada byte tem o bit mais significativo definido, exceto o byte final da sequência, que tem o bit mais significativo definido. Os sete bits restantes de cada byte são payload, com os sete bits menos significativos da quantidade no primeiro byte, os próximos sete no segundo byte e assim por diante. No caso de um LEB128 assinado (sleb128), o bit de payload mais significativo do byte final na sequência é estendido para produzir o valor final. No caso não assinado (uleb128), todos os bits não representados explicitamente são interpretados como 0.

Diagrama de bits de um valor LEB128 de dois bytes
Primeiro byte Segundo byte
1 bit6 bit5 bit4 bit3 bit2 bit1 bit0 0 bit13 bit12 bit11 bit10 bit9 bit8 bit7

A variante uleb128p1 é usada para representar um valor assinado, em que a representação é do valor mais um codificado como uleb128. Isso faz com que a codificação de -1 (considerada como o valor não assinado 0xffffffff) — mas nenhum outro número negativo — seja um único byte e seja útil exatamente nos casos em que o número representado precisa ser não negativo ou -1 (ou 0xffffffff) e em que nenhum outro valor negativo é permitido (ou em que valores não assinados grandes provavelmente não serão necessários).

Confira alguns exemplos de formatos:

Sequência codificada Como sleb128 Como uleb128 Como uleb128p1
0000-1
01110
7f-1127126
80 7f-1281625616255

Layout do arquivo

Nome Formato Descrição
cabeçalho header_item o cabeçalho
string_ids string_id_item[] lista de identificadores de string. São identificadores de todas as strings usadas por esse arquivo, seja para nomenclatura interna (por exemplo, descritores de tipo) ou como objetos constantes referenciados pelo código. Essa lista precisa ser classificada pelo conteúdo da string, usando valores de ponto de código UTF-16 (não de forma específica para a localidade) e não pode conter entradas duplicadas.
type_ids type_id_item[] Lista de identificadores de tipo. Esses são identificadores de todos os tipos (classes, matrizes ou tipos primitivos) mencionados por este arquivo, definidos ou não. Essa lista precisa ser classificada pelo índice string_id e não pode conter entradas duplicadas.
proto_ids proto_id_item[] lista de identificadores de protótipos de método. São identificadores de todos protótipos mencionados neste arquivo. Essa lista precisa ser classificada em ordem principal do tipo de retorno (por índice type_id) e, em seguida, por lista de argumentos (ordenação alfabética, argumentos individuais ordenados por índice type_id). A lista não pode conter entradas duplicadas.
field_ids field_id_item[] lista de identificadores de campo. São identificadores de todos os campos a que este arquivo faz referência, definidos ou não no arquivo. Essa lista precisa ser classificada, em que o tipo de definição (pelo índice type_id) é a ordem principal, o nome do campo (pelo índice string_id) é a ordem intermediária e o tipo (pelo índice type_id) é a ordem secundária. A lista não pode conter entradas duplicadas.
method_ids method_id_item[] lista de identificadores de método. São identificadores de todos os métodos referenciados por este arquivo, definidos ou não no arquivo. Essa lista precisa ser classificada, em que o tipo de definição (pelo índice type_id) é a ordem principal, o nome do método (pelo índice string_id) é a ordem intermediária e o protótipo do método (pelo índice proto_id) é a ordem secundária. A lista não pode conter entradas duplicadas.
class_defs class_def_item[] lista de definições de classe. As classes precisam ser ordenadas de modo que a superclasse de uma determinada classe e as interfaces implementadas apareçam na lista antes da classe de referência. Além disso, é inválido que uma definição para a classe com o mesmo nome apareça mais de uma vez na lista.
call_site_ids call_site_id_item[] lista de identificadores de chamadas do site. São identificadores de todos os locais de chamada a que este arquivo faz referência, definidos ou não no arquivo. Essa lista precisa ser classificada em ordem crescente de call_site_off.
method_handles method_handle_item[] lista de identificadores de método. Uma lista de todos os identificadores de método referidos por este arquivo, definidos ou não no arquivo. Essa lista não é classificada e pode conter duplicatas que correspondem logicamente a diferentes instâncias de identificador de método.
dados ubyte[] área de dados, que contém todos os dados de suporte das tabelas listadas acima. Itens diferentes têm requisitos de alinhamento diferentes, e bytes de preenchimento são inseridos antes de cada item, se necessário, para alcançar o alinhamento adequado.
link_data ubyte[] dados usados em arquivos vinculados de forma estática. O formato dos dados nesta seção não é especificado neste documento. Essa seção está vazia em arquivos não vinculados, e as implementações do ambiente de execução podem usá-la como acharem melhor.

Formato do contêiner

A versão 41 apresenta um novo formato de contêiner para dados DEX com o objetivo de economizar espaço. Esse formato de contêiner permite que vários arquivos DEX lógicos sejam combinados em um único arquivo físico. O novo formato é basicamente uma concatenação simples de arquivos no formato anterior, com algumas diferenças:

  • O file_size é o tamanho do arquivo lógico, não do arquivo físico. Ele pode ser usado para iterar sobre todos os arquivos lógicos no contêiner.
  • Os arquivos dex lógicos podem fazer referência a dados posteriores no contêiner, mas não anteriores. Isso permite que os arquivos dex compartilhem dados, como strings, entre eles.
  • Todos os deslocamentos são relativos ao arquivo físico. Nenhum deslocamento é relativo ao cabeçalho. Isso garante que as seções com deslocamentos possam ser compartilhadas entre arquivos lógicos.
  • O cabeçalho adiciona dois novos campos para descrever os limites do contêiner. Essa é uma verificação de consistência adicional e facilita a transferência de código para o novo formato.
  • data_size e data_off não são mais usados. Os dados podem ser distribuídos em vários arquivos lógicos e não precisam ser contíguos.

Definições de bit, string e constantes

DEX_FILE_MAGIC

Incorporado em header_item

A matriz/string constante DEX_FILE_MAGIC é a lista de bytes que precisa aparecer no início de um arquivo .dex para que ele seja reconhecido como tal. O valor intencionalmente contém uma nova linha ("\n" ou 0x0a) e um byte nulo ("\0" ou 0x00) para ajudar na detecção de determinadas formas de corrupção. O valor também codifica um número de versão de formato como três dígitos decimais, que deve aumentar monotonicamente ao longo do tempo conforme o formato evolui.

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

Observação:o suporte à versão 040 do formato foi adicionado na versão do Android 10.0, que estendeu o conjunto de caracteres permitidos em SimpleNames.

Observação:o suporte à versão 039 do formato foi adicionado na versão do Android 9.0, que introduziu dois novos bytecodes, const-method-handle e const-method-type. Elas são descritas na tabela Resumo do conjunto de bytecode. No Android 10, a versão 039 estende o formato de arquivo DEX para incluir informações de API ocultas que só são aplicáveis a arquivos DEX no caminho da classe de inicialização.

Observação:o suporte à versão 038 do formato foi adicionado na versão Android 8.0. A versão 038 adicionou novos bytecodes (invoke-polymorphic e invoke-custom) e dados para identificadores de método.

Observação:o suporte para a versão 037 do formato foi adicionado na versão do Android 7.0. Antes da versão 037, a maioria das versões do Android usava a versão 035 do formato. A única diferença entre as versões 035 e 037 é a adição de métodos padrão e o ajuste do invoke.

Observação:pelo menos algumas versões anteriores do formato foram usadas em lançamentos de software públicos amplamente disponíveis. Por exemplo, a versão 009 foi usada para as versões M3 da plataforma Android (novembro a dezembro de 2007), e a versão 013 foi usada para as versões M5 da plataforma Android (fevereiro a março de 2008). Em vários aspectos, essas versões anteriores do formato são significativamente diferentes da versão descrita neste documento.

ENDIAN_CONSTANT e REVERSE_ENDIAN_CONSTANT

Incorporado em header_item

A constante ENDIAN_CONSTANT é usada para indicar o endianidade do arquivo em que ela é encontrada. Embora o formato .dex padrão seja little-endian, as implementações podem escolher realizar a troca de bytes. Se uma implementação encontrar um cabeçalho com endian_tag como REVERSE_ENDIAN_CONSTANT em vez de ENDIAN_CONSTANT, ela saberá que o arquivo foi trocado de bytes do formulário esperado.

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

NO_INDEX

Incorporado em class_def_item e debug_info_item

A constante NO_INDEX é usada para indicar que um valor de índice está ausente.

Observação:esse valor não é definido como 0, porque esse é, na verdade, um índice válido.

O valor escolhido para NO_INDEX pode ser representado como um único byte na codificação uleb128p1.

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

definições de access_flags

Incorporado em class_def_item, encoded_field, encoded_method e InnerClass

Os campos de bits dessas flags são usados para indicar a acessibilidade e as propriedades gerais de classes e membros de classe.

Nome Valor Para classes (e anotações InnerClass) Para campos Para métodos
ACC_PUBLIC 0x1 public: visível em todos os lugares public: visível em todos os lugares public: visível em todos os lugares
ACC_PRIVATE 0x2 * private: visível apenas para a classe de definição private: visível apenas para a classe de definição private: visível apenas para a classe de definição
ACC_PROTECTED 0x4 * protected: visível para pacotes e subclasses protected: visível para pacotes e subclasses protected: visível para pacotes e subclasses
ACC_STATIC 0x8 * static: não é construído com uma referência this externa static: global para definir a classe static: não aceita um argumento this
ACC_FINAL 0x10 final: não pode ser subclassificado final: imutável após a construção final: não pode ser substituído
ACC_SYNCHRONIZED 0x20     synchronized: bloqueio associado adquirido automaticamente durante a chamada para este método.

Observação:isso só é válido quando ACC_NATIVE também está definido.

ACC_VOLATILE 0x40   volatile: regras de acesso especiais para ajudar com a segurança de linhas de execução  
ACC_BRIDGE 0x40     método de ponte, adicionado automaticamente pelo compilador como uma ponte segura para tipos
ACC_TRANSIENT 0x80   transient: não ser salvo pela serialização padrão  
ACC_VARARGS 0x80     O último argumento precisa ser tratado como um argumento "rest" pelo compilador
ACC_NATIVE 0x100     native: implementado em código nativo
ACC_INTERFACE 0x200 interface: classe abstrata com várias implementações    
ACC_ABSTRACT 0x400 abstract: não pode ser instanciado diretamente   abstract: não implementado por esta classe
ACC_STRICT 0x800     strictfp: regras rigorosas para a aritmética de ponto flutuante
ACC_SYNTHETIC 0x1000 não está definido diretamente no código-fonte não está definido diretamente no código-fonte não está definido diretamente no código-fonte
ACC_ANNOTATION 0x2000 declarada como uma classe de anotação    
ACC_ENUM 0x4000 declarado como um tipo enumerado declarado como um valor enumerado  
(não usado) 0x8000      
ACC_CONSTRUCTOR 0x10000     método construtor (inicializador de classe ou de instância)
ACC_DECLARED_
SYNCHRONIZED
0x20000     declarou synchronized.

Observação:isso não tem efeito na execução (exceto na reflexão dessa flag).

* Permitido apenas para anotações InnerClass e não pode ser usado em class_def_item.

Codificação UTF-8 modificada

Para facilitar o suporte legado, o formato .dex codifica os dados de string em um formato UTF-8 modificado padrão de fato, chamado de MUTF-8. Esse formulário é idêntico ao UTF-8 padrão, exceto:

  • Somente as codificações de um, dois e três bytes são usadas.
  • Os pontos de código no intervalo U+10000U+10ffff são codificados como um par substituto, cada um representado como um valor codificado de três bytes.
  • O ponto de código U+0000 é codificado na forma de dois bytes.
  • Um byte nulo simples (valor 0) indica o fim de uma string, como é a interpretação padrão da linguagem C.

Os dois primeiros itens acima podem ser resumidos como: MUTF-8 é um formato de codificação para UTF-16, em vez de ser um formato de codificação mais direto para caracteres Unicode.

Os dois últimos itens acima permitem incluir o ponto de código U+0000 em uma string e ainda manipulá-lo como uma string terminada em nulo no estilo C.

No entanto, a codificação especial de U+0000 significa que, ao contrário do UTF-8 normal, o resultado de chamar a função C padrão strcmp() em um par de strings MUTF-8 nem sempre indica o resultado assinado corretamente da comparação de strings diferentes. Quando a ordenação (não apenas a igualdade) é uma preocupação, a maneira mais direta de comparar strings MUTF-8 é decodificá-las caractere por caractere e comparar os valores decodificados. No entanto, implementações mais inteligentes também são possíveis.

Consulte O padrão Unicode para mais informações sobre a codificação de caracteres. O MUTF-8 é mais parecido com a codificação CESU-8 (relativamente menos conhecida) do que com o UTF-8 em si.

encoded_value encoding

Incorporado em annotation_element e encoded_array_item

Um encoded_value é um pedaço codificado de dados (quase) arbitrários estruturados hierarquicamente. A codificação precisa ser compacta e simples de analisar.

Nome Formato Descrição
(value_arg << 5) | value_type ubyte Byte que indica o tipo do value imediatamente subsequente, além de um argumento de esclarecimento opcional nos três bits de ordem alta. Confira abaixo as várias definições de value. Na maioria dos casos, value_arg codifica o comprimento do value imediatamente subsequente em bytes, como (size - 1), por exemplo, 0 significa que o valor requer um byte, e 7 significa que ele requer oito bytes. No entanto, há exceções, conforme observado abaixo.
value ubyte[] bytes que representam o valor, variável em comprimento e interpretado de maneira diferente para diferentes bytes value_type, embora sempre little-endian. Confira as várias definições de valor abaixo para mais detalhes.

Formatos de valor

Nome do tipo value_type Formato value_arg Formato value Descrição
VALUE_BYTE 0x00 (nenhum; precisa ser 0) ubyte[1] valor inteiro de um byte assinado
VALUE_SHORT 0x02 size - 1 (0…1) ubyte[size] Valor inteiro de dois bytes assinado, com extensão de sinal
VALUE_CHAR 0x03 size - 1 (0…1) ubyte[size] Valor inteiro de dois bytes não assinado, com extensão de zero
VALUE_INT 0x04 size - 1 (0…3) ubyte[size] valor inteiro assinado de quatro bytes, com extensão de sinal
VALUE_LONG 0x06 size - 1 (0…7) ubyte[size] valor inteiro assinado de oito bytes, com sinal estendido
VALUE_FLOAT 0x10 size - 1 (0…3) ubyte[size] padrão de quatro bytes, estendido a zero à direita e interpretado como um valor de ponto flutuante de 32 bits IEEE754
VALUE_DOUBLE 0x11 size - 1 (0…7) ubyte[size] padrão de bits de oito bytes, estendido a zero à direita e interpretado como um valor de ponto flutuante de 64 bits IEEE754
VALUE_METHOD_TYPE 0x15 size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão de zero), interpretado como um índice na seção proto_ids e que representa um valor de tipo de método
VALUE_METHOD_HANDLE 0x16 size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão zero), interpretado como um índice na seção method_handles e que representa um valor de identificador de método
VALUE_STRING 0x17 size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão de zero), interpretado como um índice na seção string_ids e que representa um valor de string
VALUE_TYPE 0x18 size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão de zero), interpretado como um índice na seção type_ids e que representa um valor de tipo/classe reflexivo
VALUE_FIELD 0x19 size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão de zero), interpretado como um índice na seção field_ids e que representa um valor de campo reflexivo
VALUE_METHOD 0x1a size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão de zero), interpretado como um índice na seção method_ids e que representa um valor de método reflexivo.
VALUE_ENUM 0x1b size - 1 (0…3) ubyte[size] Valor inteiro de quatro bytes sem sinal (com extensão de zero), interpretado como um índice na seção field_ids e que representa o valor de uma constante de tipo enumerado
VALUE_ARRAY 0x1c (nenhum; precisa ser 0) encoded_array uma matriz de valores, no formato especificado por "formato encoded_array" abaixo. O tamanho do value está implícito na codificação.
VALUE_ANNOTATION 0x1d (nenhum; precisa ser 0) encoded_annotation uma subanotação, no formato especificado por "formato encoded_annotation" abaixo. O tamanho do value está implícito na codificação.
VALUE_NULL 0x1e (nenhum; precisa ser 0) (nenhuma) Valor de referência null
VALUE_BOOLEAN 0x1f booleano (0…1) (nenhuma) valor de um bit: 0 para false e 1 para true. O bit é representado em value_arg.

formato encoded_array

Nome Formato Descrição
size uleb128 número de elementos na matriz
valores encoded_value[size] uma série de sequências de bytes encoded_value size no formato especificado por esta seção, concatenadas sequencialmente.

formato encoded_annotation

Nome Formato Descrição
type_idx uleb128 tipo da anotação. Ele precisa ser um tipo de classe (não matriz ou primitivo).
size uleb128 número de mapeamentos de nome-valor nesta anotação
elementos annotation_element[size] elementos da anotação, representados diretamente em linha (não como deslocamentos). Os elementos precisam ser classificados em ordem crescente pelo índice string_id.

formato do annotation_element

Nome Formato Descrição
name_idx uleb128 nome do elemento, representado como um índice na seção string_ids. A string precisa estar em conformidade com a sintaxe de MemberName, definida acima.
value encoded_value valor do elemento

Sintaxe de strings

Há vários tipos de itens em um arquivo .dex que se referem a uma string. As definições no estilo BNF a seguir indicam a sintaxe aceitável para essas strings.

SimpleName

Um SimpleName é a base para a sintaxe dos nomes de outras coisas. O formato .dex permite uma certa margem de manobra aqui (muito maior do que a maioria dos idiomas de origem mais comuns). Em resumo, um nome simples consiste em qualquer caractere alfabético ou dígito de ASCII de baixo nível, alguns símbolos específicos de ASCII de baixo nível e a maioria dos pontos de código não ASCII que não são caracteres de controle, espaço ou especiais. A partir da versão 040, o formato também permite caracteres de espaço (categoria Unicode Zs). Os pontos de código substituto (no intervalo U+d800U+dfff) não são considerados caracteres de nome válidos, mas os caracteres suplementares Unicode são válidos (representados pela alternativa final da regra para SimpleNameChar) e precisam ser representados em um arquivo como pares de pontos de código substituto na codificação MUTF-8.

SimpleName
SimpleNameChar (SimpleNameChar)*
SimpleNameChar
'A''Z'
| 'a''z'
| '0''9'
| ' ' desde a versão 040 do DEX
| '$'
| '-'
| '_'
| U+00a0 desde a versão 040 do DEX
| U+00a1U+1fff
| U+2000U+200a desde a versão 040 do DEX
| U+2010U+2027
| U+202f desde a versão 040 do DEX
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

MemberName

usado por field_id_item e method_id_item

Um MemberName é o nome de um membro de uma classe, sendo campos, métodos e classes internas.

MemberName
SimpleName
| '<' SimpleName '>'

FullClassName

Um FullClassName é um nome de classe totalmente qualificado, incluindo um especificador de pacote opcional seguido por um nome obrigatório.

FullClassName
OptionalPackagePrefix SimpleName
OptionalPackagePrefix
(SimpleName '/')*

TypeDescriptor

Usado por type_id_item

Um TypeDescriptor é a representação de qualquer tipo, incluindo primitivos, classes, matrizes e void. Confira abaixo o significado das várias versões.

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

ShortyDescriptor

Usado por proto_id_item

Um ShortyDescriptor é a representação em forma curta de um protótipo de método, incluindo tipos de retorno e de parâmetro, exceto que não há diferença entre vários tipos de referência (classe ou matriz). Em vez disso, todos os tipos de referência são representados por um único caractere 'L'.

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

Semântica de TypeDescriptor

Este é o significado de cada uma das variantes de TypeDescriptor.

Sintaxe Significado
V void: válido apenas para tipos de retorno
Z boolean
B byte
S short
C char
I int
J long
F float
D double
Lfully/qualified/Name; a classe fully.qualified.Name
[descriptor matriz de descriptor, que pode ser usada de forma recursiva para matrizes de matrizes, embora seja inválido ter mais de 255 dimensões.

Itens e estruturas relacionadas

Esta seção inclui definições para cada um dos itens de nível superior que podem aparecer em um arquivo .dex.

header_item

Aparece na seção do cabeçalho

Alinhamento: 4 bytes

Nome Formato Descrição
mágica ubyte[8] = DEX_FILE_MAGIC valor mágico. Consulte a discussão acima em "DEX_FILE_MAGIC" para mais detalhes.
checksum uint Soma de verificação adler32 do restante do arquivo (tudo, exceto magic e este campo); usada para detectar a corrupção do arquivo
assinatura ubyte[20] Assinatura SHA-1 (hash) do restante do arquivo (tudo, exceto magic, checksum e este campo); usada para identificar arquivos de maneira exclusiva
file_size uint

tamanho do arquivo inteiro (incluindo o cabeçalho), em bytes (v40 ou anterior)

Distância em bytes do início deste cabeçalho até o próximo cabeçalho ou até o fim de todo o arquivo (o contêiner). (v41 ou mais recente)

header_size uint

tamanho do cabeçalho (toda a seção), em bytes. Isso permite pelo menos uma quantidade limitada de compatibilidade com versões anteriores/posteriores sem invalidar o formato.

Precisa ser 0x70 (112) bytes (v40 ou anterior)

Precisa ser 0x78 (120) bytes (v41 ou mais recente)

endian_tag uint = ENDIAN_CONSTANT tag de endianidade. Consulte a discussão acima em "ENDIAN_CONSTANT e REVERSE_ENDIAN_CONSTANT" para mais detalhes.
link_size uint tamanho da seção de link ou 0 se o arquivo não estiver vinculado de forma estática
link_off uint deslocamento do início do arquivo até a seção do link ou 0 se link_size == 0. O deslocamento, se diferente de zero, precisa ser um deslocamento para a seção link_data. O formato dos dados apontados não é especificado neste documento. Esse campo de cabeçalho (e o anterior) são deixados como ganchos para uso por implementações de tempo de execução.
map_off uint deslocamento do início do arquivo para o item do mapa. O deslocamento, que precisa ser diferente de zero, precisa ser um deslocamento na seção data, e os dados precisam estar no formato especificado por "map_list" abaixo.
string_ids_size uint contagem de strings na lista de identificadores de string
string_ids_off uint deslocamento do início do arquivo para a lista de identificadores de string ou 0 se string_ids_size == 0 (um caso extremo estranho). O deslocamento, se diferente de zero, precisa estar no início da seção string_ids.
type_ids_size uint contagem de elementos na lista de identificadores de tipo, no máximo 65.535
type_ids_off uint deslocamento do início do arquivo para a lista de identificadores de tipo ou 0 se type_ids_size == 0 (um caso extremo estranho). O deslocamento, se diferente de zero, precisa ser o início da seção type_ids.
proto_ids_size uint contagem de elementos na lista de identificadores de protótipo, no máximo 65.535
proto_ids_off uint deslocamento do início do arquivo para a lista de identificadores de protótipo ou 0 se proto_ids_size == 0 (um caso extremo estranho). O deslocamento, se diferente de zero, precisa ser o início da seção proto_ids.
field_ids_size uint contagem de elementos na lista de identificadores de campo
field_ids_off uint deslocamento da lista de identificadores de campo até o início do arquivo ou 0 se field_ids_size == 0. O deslocamento, se diferente de zero, precisa ser o início da seção field_ids.
method_ids_size uint contagem de elementos na lista de identificadores de método
method_ids_off uint deslocamento do início do arquivo para a lista de identificadores de método ou 0 se method_ids_size == 0. O deslocamento, se diferente de zero, precisa ser o início da seção method_ids.
class_defs_size uint contagem de elementos na lista de definições de classe
class_defs_off uint deslocamento do início do arquivo para a lista de definições de classe ou 0 se class_defs_size == 0 (um caso extremo estranho). O deslocamento, se diferente de zero, precisa estar no início da seção class_defs.
data_size uint

Tamanho da seção data em bytes. Precisa ser um múltiplo par de sizeof(uint). (v40 ou anterior)

Não utilizado (v41 ou mais recente)

data_off uint

deslocamento do início do arquivo até o início da seção data (v40 ou anterior)

Não utilizado (v41 ou mais recente)

container_size uint

este campo não existe. Pode-se presumir que ele é igual a file_size. (v40 ou anterior)

tamanho de todo o arquivo (incluindo outros cabeçalhos dex e os dados deles). (v41 ou mais recente)

header_offset uint

este campo não existe. Pode-se presumir que ele é igual a 0. (v40 ou anterior)

deslocamento do início do arquivo até o início deste cabeçalho. (v41 ou mais recente)

map_list

Aparece na seção de dados

Referência de header_item

Alinhamento: 4 bytes

Esta é uma lista de todo o conteúdo de um arquivo, em ordem. Ele contém alguma redundância em relação ao header_item, mas tem como objetivo ser uma forma fácil de iterar um arquivo inteiro. Um determinado tipo precisa aparecer no máximo uma vez em um mapa, mas não há restrição sobre quais tipos de ordem podem aparecer, exceto as restrições implícitas no restante do formato (por exemplo, uma seção header precisa aparecer primeiro, seguida por uma seção string_ids etc.). Além disso, as entradas do mapa precisam ser ordenadas por deslocamento inicial e não podem se sobrepor.

Nome Formato Descrição
size uint tamanho da lista, em entradas
list map_item[size] elementos da lista

formato de map_item

Nome Formato Descrição
type ushort tipo dos itens. Consulte a tabela abaixo
unused ushort (não usado)
size uint contagem do número de itens a serem encontrados no deslocamento indicado
compensação uint deslocamento do início do arquivo para os itens em questão

Códigos de tipo

Tipo de item Constante Valor Tamanho do item em bytes
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 implícita; precisa ser analisada
code_item TYPE_CODE_ITEM 0x2001 implícita; precisa ser analisada
string_data_item TYPE_STRING_DATA_ITEM 0x2002 implícita; precisa ser analisada
debug_info_item TYPE_DEBUG_INFO_ITEM 0x2003 implícita; precisa ser analisada
annotation_item TYPE_ANNOTATION_ITEM 0x2004 implícita; precisa ser analisada
encoded_array_item TYPE_ENCODED_ARRAY_ITEM 0x2005 implícita; precisa ser analisada
annotations_directory_item TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006 implícita; precisa ser analisada
hiddenapi_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000 implícita; precisa ser analisada

string_id_item

Aparece na seção string_ids

Alinhamento: 4 bytes

Nome Formato Descrição
string_data_off uint deslocamento do início do arquivo para os dados da string desse item. O deslocamento precisa ser para um local na seção data, e os dados precisam estar no formato especificado por "string_data_item" abaixo. Não há requisito de alinhamento para o deslocamento.

string_data_item

Aparece na seção de dados

Alinhamento: nenhum (alinhamento de byte)

Nome Formato Descrição
utf16_size uleb128 tamanho dessa string, em unidades de código UTF-16, que é a "string length" em muitos sistemas. Ou seja, esse é o comprimento decodificado da cadeia. O comprimento codificado é implícito pela posição do byte 0.
dados ubyte[] uma série de unidades de código MUTF-8 (também conhecidas como octetos ou bytes) seguidas por um byte de valor 0. Consulte "Codificação MUTF-8 (UTF-8 modificado)" acima para mais detalhes e discussão sobre o formato de dados.

Observação:é aceitável ter uma string que inclua (a forma codificada de) unidades de código substituto UTF-16 (ou seja, U+d800U+dfff) isoladas ou fora de ordem em relação à codificação usual de Unicode em UTF-16. Cabe aos usos de nível mais alto de strings rejeitar essas codificações inválidas, se apropriado.

type_id_item

Aparece na seção "type_ids"

Alinhamento: 4 bytes

Nome Formato Descrição
descriptor_idx uint índice na lista string_ids para a string de descritor desse tipo. A string precisa estar em conformidade com a sintaxe de TypeDescriptor, definida acima.

proto_id_item

Aparece na seção proto_ids

Alinhamento: 4 bytes

Nome Formato Descrição
shorty_idx uint índice na lista string_ids para a string de descritor abreviada desse protótipo. A string precisa estar em conformidade com a sintaxe de ShortyDescriptor, definida acima, e precisa corresponder ao tipo de retorno e aos parâmetros desse item.
return_type_idx uint índice na lista type_ids para o tipo de retorno deste protótipo
parameters_off uint deslocamento do início do arquivo para a lista de tipos de parâmetro do protótipo ou 0 se o protótipo não tiver parâmetros. Esse deslocamento, se diferente de zero, precisa estar na seção data, e os dados precisam estar no formato especificado por "type_list" abaixo. Além disso, não deve haver referência ao tipo void na lista.

field_id_item

Aparece na seção field_ids

Alinhamento: 4 bytes

Nome Formato Descrição
class_idx ushort índice na lista type_ids para o definidor desse campo. Ele precisa ser um tipo de classe, e não um tipo primitivo ou matriz.
type_idx ushort índice na lista type_ids para o tipo de campo
name_idx uint índice na lista string_ids para o nome desse campo. A string precisa estar em conformidade com a sintaxe de MemberName, definida acima.

method_id_item

Aparece na seção method_ids

Alinhamento: 4 bytes

Nome Formato Descrição
class_idx ushort índice na lista type_ids para o definidor desse método. Ele precisa ser um tipo de classe ou matriz, e não um tipo primitivo.
proto_idx ushort índice na lista proto_ids para o protótipo deste método
name_idx uint índice na lista string_ids para o nome desse método. A string precisa estar em conformidade com a sintaxe de MemberName, definida acima.

class_def_item

Aparece na seção class_defs

Alinhamento: 4 bytes

Nome Formato Descrição
class_idx uint índice na lista type_ids para essa classe. Ele precisa ser um tipo de classe, e não um tipo primitivo ou matriz.
access_flags uint flags de acesso para a classe (public, final etc.). Consulte "Definições de access_flags" para mais detalhes.
superclass_idx uint índice na lista type_ids da superclasse ou o valor constante NO_INDEX se essa classe não tiver uma superclasse (ou seja, se for uma classe raiz, como Object). Se presente, esse valor precisa ser um tipo de classe, e não uma matriz ou um tipo primitivo.
interfaces_off uint deslocamento do início do arquivo para a lista de interfaces ou 0 se não houver nenhuma. Esse deslocamento precisa estar na seção data, e os dados precisam estar no formato especificado por "type_list" abaixo. Cada um dos elementos da lista precisa ser um tipo de classe (não um array ou tipo primitivo) e não pode ter duplicatas.
source_file_idx uint índice na lista string_ids para o nome do arquivo que contém a origem original (pelo menos a maioria) dessa classe, ou o valor especial NO_INDEX para representar a falta dessas informações. O debug_info_item de qualquer método pode substituir esse arquivo de origem, mas a expectativa é que a maioria das classes venha apenas de um arquivo de origem.
annotations_off uint deslocamento do início do arquivo para a estrutura de anotações dessa classe ou 0 se não houver anotações nessa classe. Esse deslocamento, se diferente de zero, precisa estar na seção data, e os dados precisam estar no formato especificado por "annotations_directory_item" abaixo, com todos os itens que se referem a essa classe como o definidor.
class_data_off uint Deslocamento do início do arquivo para os dados de classe associados a esse item ou 0 se não houver dados de classe para essa classe. Isso pode acontecer, por exemplo, se essa classe for uma interface de marcador. O deslocamento, se diferente de zero, precisa estar na seção data, e os dados precisam estar no formato especificado por "class_data_item" abaixo, com todos os itens que se referem a essa classe como o definidor.
static_values_off uint deslocamento do início do arquivo para a lista de valores iniciais para campos static ou 0 se não houver nenhum (e todos os campos static forem inicializados com 0 ou null). Esse deslocamento precisa estar na seção data, e os dados precisam estar no formato especificado por "encoded_array_item" abaixo. O tamanho da matriz não pode ser maior que o número de campos static declarados por essa classe, e os elementos correspondem aos campos static na mesma ordem declarada no field_list correspondente. O tipo de cada elemento de matriz precisa corresponder ao tipo declarado do campo correspondente. Se houver menos elementos na matriz do que campos static, os campos restantes serão inicializados com um 0 ou null adequado ao tipo.

call_site_id_item

Aparece na seção call_site_ids

Alinhamento: 4 bytes

Nome Formato Descrição
call_site_off uint deslocamento do início do arquivo para chamar a definição do site. O deslocamento precisa estar na seção de dados, e os dados precisam estar no formato especificado por "call_site_item" abaixo.

call_site_item

Aparece na seção de dados

Alinhamento: nenhum (alinhamento de byte)

O call_site_item é um item de matriz codificado cujos elementos correspondem aos argumentos fornecidos a um método de vinculação de inicialização. Os três primeiros argumentos são:

  1. Um identificador de método que representa o método de vinculação de inicialização (VALUE_METHOD_HANDLE).
  2. Um nome de método que o linkador de inicialização precisa resolver (VALUE_STRING).
  3. Um tipo de método correspondente ao tipo do nome do método a ser resolvido (VALUE_METHOD_TYPE).

Todos os argumentos adicionais são valores constantes transmitidos para o método de vinculação de inicialização. Esses argumentos são transmitidos em ordem e sem conversões de tipo.

O gerenciador de método que representa o método do vinculador de inicialização precisa ter o tipo de retorno java.lang.invoke.CallSite. Os três primeiros tipos de parâmetro são:

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

Os tipos de parâmetro de outros argumentos são determinados pelos valores constantes.

method_handle_item

Aparece na seção method_handles

Alinhamento: 4 bytes

Nome Formato Descrição
method_handle_type ushort tipo do identificador do método. Consulte a tabela abaixo.
unused ushort (não usado)
field_or_method_id ushort ID de campo ou método, dependendo se o tipo de identificador de método é um acessador ou um invocador de método.
unused ushort (não usado)

Códigos de tipo de manipulador de método

Constante Valor Descrição
METHOD_HANDLE_TYPE_STATIC_PUT 0x00 O handle de método é um setter de campo estático (acessor)
METHOD_HANDLE_TYPE_STATIC_GET 0x01 O handle de método é um getter de campo estático (acessador)
METHOD_HANDLE_TYPE_INSTANCE_PUT 0x02 O identificador de método é um setter de campo de instância (acessador)
METHOD_HANDLE_TYPE_INSTANCE_GET 0x03 O handle de método é um getter de campo de instância (acessório)
METHOD_HANDLE_TYPE_INVOKE_STATIC 0x04 O handle de método é um invocador de método estático
METHOD_HANDLE_TYPE_INVOKE_INSTANCE 0x05 O manipulador de método é um invocador de método de instância
METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR 0x06 O handle de método é um invocador de método construtor
METHOD_HANDLE_TYPE_INVOKE_DIRECT 0x07 O handle de método é um invocador de método direto
METHOD_HANDLE_TYPE_INVOKE_INTERFACE 0x08 O handle de método é um invocador de método de interface

class_data_item

Referência de class_def_item

Aparece na seção de dados

Alinhamento: nenhum (alinhamento de byte)

Nome Formato Descrição
static_fields_size uleb128 o número de campos estáticos definidos neste item
instance_fields_size uleb128 o número de campos de instância definidos neste item
direct_methods_size uleb128 o número de métodos diretos definidos neste item
virtual_methods_size uleb128 o número de métodos virtuais definidos neste item
static_fields encoded_field[static_fields_size] os campos estáticos definidos, representados como uma sequência de elementos codificados. Os campos precisam ser classificados por field_idx em ordem crescente.
instance_fields encoded_field[instance_fields_size] os campos de instância definidos, representados como uma sequência de elementos codificados. Os campos precisam ser classificados por field_idx em ordem crescente.
direct_methods encoded_method[direct_methods_size] os métodos diretos definidos (qualquer um de static, private ou construtor), representados como uma sequência de elementos codificados. Os métodos precisam ser classificados por method_idx em ordem crescente.
virtual_methods encoded_method[virtual_methods_size] os métodos virtuais definidos (nenhum de static, private ou construtor), representados como uma sequência de elementos codificados. Essa lista não deve incluir métodos herdados, a menos que sejam substituídos pela classe que o item representa. Os métodos precisam ser classificados por method_idx em ordem crescente. O method_idx de um método virtual não pode ser o mesmo que qualquer método direto.

Observação:todas as instâncias field_id e method_id dos elementos precisam se referir à mesma classe de definição.

formato do encoded_field

Nome Formato Descrição
field_idx_diff uleb128 índice na lista field_ids para a identidade desse campo (inclui o nome e o descritor), representado como uma diferença em relação ao índice do elemento anterior na lista. O índice do primeiro elemento de uma lista é representado diretamente.
access_flags uleb128 flags de acesso para o campo (public, final etc.). Consulte "Definições de access_flags" para mais detalhes.

formato encoded_method

Nome Formato Descrição
method_idx_diff uleb128 índice na lista method_ids para a identidade deste método (inclui o nome e o descritor), representado como uma diferença do índice do elemento anterior na lista. O índice do primeiro elemento de uma lista é representado diretamente.
access_flags uleb128 flags de acesso para o método (public, final etc.). Consulte "Definições de access_flags" para mais detalhes.
code_off uleb128 deslocamento do início do arquivo para a estrutura de código desse método ou 0 se esse método for abstract ou native. O deslocamento precisa ser para um local na seção data. O formato dos dados é especificado por "code_item" abaixo.

type_list

Referenciado em class_def_item e proto_id_item

Aparece na seção de dados

Alinhamento: 4 bytes

Nome Formato Descrição
size uint tamanho da lista, em entradas
list type_item[size] elementos da lista

formato de type_item

Nome Formato Descrição
type_idx ushort índice na lista type_ids

code_item

Referência de encoded_method

Aparece na seção de dados

Alinhamento: 4 bytes

Nome Formato Descrição
registers_size ushort o número de registros usados por esse código
ins_size ushort o número de palavras de argumentos recebidos para o método a que este código se destina
outs_size ushort o número de palavras de espaço de argumento de saída necessárias para essa invocação de método
tries_size ushort o número de try_items para essa instância. Se não for zero, eles vão aparecer como a matriz tries logo após o insns nesta instância.
debug_info_off uint deslocamento do início do arquivo até a sequência de informações de depuração (números de linha + informações de variáveis locais) para esse código ou 0 se não houver informações. O deslocamento, se diferente de zero, precisa ser para um local na seção data. O formato dos dados é especificado por "debug_info_item" abaixo.
insns_size uint tamanho da lista de instruções, em unidades de código de 16 bits
insns ushort[insns_size] matriz real de bytecode. O formato do código em uma matriz insns é especificado pelo documento complementar Dalvik bytecode. Observe que, embora isso seja definido como uma matriz de ushort, há algumas estruturas internas que preferem o alinhamento de quatro bytes. Além disso, se isso acontecer em um arquivo com troca de endian, a troca será feita apenas em instâncias ushort individuais, e não nas estruturas internas maiores.
preenchimento ushort (opcional) = 0 dois bytes de preenchimento para alinhar tries com quatro bytes. Esse elemento só está presente se tries_size for diferente de zero e insns_size for ímpar.
tentativas try_item[tries_size] (opcional) matriz que indica onde as exceções do código são capturadas e como processá-las. Os elementos da matriz não podem se sobrepor no intervalo e precisam estar em ordem de endereço de baixo para alto. Esse elemento só estará presente se tries_size for diferente de zero.
gerenciadores encoded_catch_handler_list (opcional) Bytes que representam uma lista de listas de tipos de captura e endereços de manipulador associados. Cada try_item tem um deslocamento por byte nessa estrutura. Esse elemento só está presente se tries_size for diferente de zero.

try_item format

Nome Formato Descrição
start_addr uint endereço inicial do bloco de código coberto por essa entrada. O endereço é uma contagem de unidades de código de 16 bits até o início da primeira instrução coberta.
insn_count ushort número de unidades de código de 16 bits cobertas por essa entrada. A última unidade de código coberta (inclusive) é start_addr + insn_count - 1.
handler_off ushort deslocamento em bytes do início do encoded_catch_hander_list associado ao encoded_catch_handler para essa entrada. Precisa ser um deslocamento para o início de um encoded_catch_handler.

formato encoded_catch_handler_list

Nome Formato Descrição
size uleb128 tamanho desta lista, em entradas
list encoded_catch_handler[handlers_size] Lista real de listas de manipuladores, representada diretamente (não como deslocamentos) e concatenada sequencialmente

formato encoded_catch_handler

Nome Formato Descrição
size sleb128 número de tipos de capturas nesta lista. Se não for positivo, será negativo do número de tipos de captura, e as capturas serão seguidas por um gerenciador de capturas gerais. Por exemplo: um size de 0 significa que há um catch-all, mas não há capturas explicitamente digitadas. Um size de 2 significa que há duas capturas explicitamente definidas e nenhuma captura geral. E um size de -1 significa que há uma captura digitada com uma captura geral.
gerenciadores encoded_type_addr_pair[abs(size)] fluxo de itens codificados abs(size), um para cada tipo detectado, na ordem em que os tipos precisam ser testados.
catch_all_addr uleb128 (opcional) endereço de bytecode do gerenciador "pega-tudo". Esse elemento só estará presente se size não for positivo.

formato encoded_type_addr_pair

Nome Formato Descrição
type_idx uleb128 índice na lista type_ids para o tipo de excpeção a ser detectada
addr uleb128 endereço de bytecode do manipulador de exceções associado

debug_info_item

Referência de code_item

Aparece na seção de dados

Alinhamento: nenhum (alinhamento de byte)

Cada debug_info_item define uma máquina de estados codificada em bytes inspirada no DWARF3 que, quando interpretada, emite a tabela de posições e (potencialmente) as informações de variáveis locais para um code_item. A sequência começa com um cabeçalho de comprimento variável, cujo comprimento depende do número de parâmetros do método, é seguido pelos bytecodes da máquina de estados e termina com um byte DBG_END_SEQUENCE.

A máquina de estados consiste em cinco registros. O registro address representa o deslocamento de instrução no insns_item associado em unidades de código de 16 bits. O registro address começa em 0 no início de cada sequência debug_info e precisa aumentar de forma monotonicamente. O registro line representa qual número de linha de origem deve ser associado à próxima entrada de tabela de posições emitida pela máquina de estados. Ele é inicializado no cabeçalho da sequência e pode mudar em direções positivas ou negativas, mas nunca pode ser menor que 1. O registro source_file representa o arquivo de origem a que as entradas de número de linha se referem. Ele é inicializado para o valor de source_file_idx em class_def_item. As outras duas variáveis, prologue_end e epilogue_begin, são flags booleanas (inicializadas como false) que indicam se a próxima posição emitida deve ser considerada um prólogo ou epílogo de método. A máquina de estados também precisa rastrear o nome e o tipo da última variável local em cada registro para o código DBG_RESTART_LOCAL.

O cabeçalho é o seguinte:

Nome Formato Descrição
line_start uleb128 o valor inicial do registro line da máquina de estados. Não representa uma entrada de posições real.
parameters_size uleb128 o número de nomes de parâmetros codificados. Deve haver um por parâmetro de método, excluindo o this de um método de instância, se houver.
parameter_names uleb128p1[parameters_size] índice de string do nome do parâmetro do método. Um valor codificado de NO_INDEX indica que nenhum nome está disponível para o parâmetro associado. O descritor de tipo e a assinatura são implícitos no descritor e na assinatura do método.

Os valores do código de byte são os seguintes:

Nome Valor Formato Argumentos Descrição
DBG_END_SEQUENCE 0x00 (nenhuma) encerra uma sequência de informações de depuração para um code_item
DBG_ADVANCE_PC 0x01 uleb128 addr_diff addr_diff: valor a ser adicionado ao registro de endereço avança o registro de endereço sem emitir uma entrada de posições
DBG_ADVANCE_LINE 0x02 sleb128 line_diff line_diff: valor para mudar o registro de linha avança o registro de linha sem emitir uma entrada de posições
DBG_START_LOCAL 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num: registro que vai conter local
name_idx: índice de string do nome
type_idx: índice de tipo do tipo
introduz uma variável local no endereço atual. name_idx ou type_idx podem ser NO_INDEX para indicar que o valor é desconhecido.
DBG_START_LOCAL_EXTENDED 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num: registro que vai conter local
name_idx: índice de string do nome
type_idx: índice de tipo do tipo
sig_idx: índice de string da assinatura do tipo
introduz um local com uma assinatura de tipo no endereço atual. Qualquer um dos valores name_idx, type_idx ou sig_idx pode ser NO_INDEX para indicar que o valor é desconhecido. No entanto, se sig_idx for -1, os mesmos dados poderão ser representados de forma mais eficiente usando o opcode DBG_START_LOCAL.

Observação:consulte a discussão em "dalvik.annotation.Signature" abaixo para ver as ressalvas sobre como processar assinaturas.

DBG_END_LOCAL 0x05 uleb128 register_num register_num: registro que continha local marca uma variável local ativa como fora do escopo no endereço atual
DBG_RESTART_LOCAL 0x06 uleb128 register_num register_num: registro para reiniciar introduz novamente uma variável local no endereço atual. O nome e o tipo são iguais ao último local ativo no registro especificado.
DBG_SET_PROLOGUE_END 0x07 (nenhuma) define o registro da máquina de estados prologue_end, indicando que a próxima entrada de posição adicionada precisa ser considerada o fim do prólogo de um método (um local adequado para um ponto de interrupção de método). O registro prologue_end é apagado por qualquer opcode especial (>= 0x0a).
DBG_SET_EPILOGUE_BEGIN 0x08 (nenhuma) define o registro da máquina de estados epilogue_begin, indicando que a próxima entrada de posição adicionada precisa ser considerada o início de um epílogo de método (um lugar adequado para suspender a execução antes da saída do método). O registro epilogue_begin é limpo por qualquer opcode especial (>= 0x0a).
DBG_SET_FILE 0x09 uleb128p1 name_idx name_idx: índice de string do nome do arquivo de origem; NO_INDEX se desconhecido indica que todas as entradas de número de linha subsequentes fazem referência a esse nome de arquivo de origem, em vez do nome padrão especificado em code_item
Opcodes especiais 0x0a…0xff (nenhuma) avança os registros line e address, emite uma entrada de posição e limpa prologue_end e epilogue_begin. Confira a descrição abaixo.

Operadores de código especiais

Opcodes com valores entre 0x0a e 0xff (inclusive) movem os registros line e address por uma pequena quantidade e emitem uma nova entrada de tabela de posição. A fórmula para os incrementos é a seguinte:

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

Referência de class_def_item

Aparece na seção de dados

Alinhamento: 4 bytes

Nome Formato Descrição
class_annotations_off uint deslocamento do início do arquivo para as anotações feitas diretamente na classe ou 0 se a classe não tiver anotações diretas. O deslocamento, se diferente de zero, precisa ser para um local na seção data. O formato dos dados é especificado por "annotation_set_item" abaixo.
fields_size uint contagem de campos anotados por este item
annotated_methods_size uint contagem de métodos anotados por este item
annotated_parameters_size uint contagem de listas de parâmetros de método anotadas por este item
field_annotations field_annotation[fields_size] (opcional) lista de anotações de campo associadas. Os elementos da lista precisam ser classificados em ordem crescente, por field_idx.
method_annotations method_annotation[methods_size] (opcional) lista de anotações de método associadas. Os elementos da lista precisam ser classificados em ordem crescente, por method_idx.
parameter_annotations parameter_annotation[parameters_size] (opcional) lista de anotações de parâmetros de método associados. Os elementos da lista precisam ser classificados em ordem crescente, por method_idx.

Observação:todas as instâncias field_id e method_id dos elementos precisam se referir à mesma classe de definição.

formato de field_annotation

Nome Formato Descrição
field_idx uint Índice na lista field_ids para a identidade do campo que está sendo anotado
annotations_off uint deslocamento do início do arquivo para a lista de anotações do campo. O deslocamento precisa ser para um local na seção data. O formato dos dados é especificado por "annotation_set_item" abaixo.

formato de method_annotation

Nome Formato Descrição
method_idx uint índice na lista method_ids para a identidade do método que está sendo anotado
annotations_off uint deslocamento do início do arquivo para a lista de anotações do método. O deslocamento precisa ser para um local na seção data. O formato dos dados é especificado por "annotation_set_item" abaixo.

formato de parameter_annotation

Nome Formato Descrição
method_idx uint índice na lista method_ids para a identidade do método cujos parâmetros estão sendo anotados
annotations_off uint deslocamento do início do arquivo para a lista de anotações dos parâmetros do método. O deslocamento precisa ser para um local na seção data. O formato dos dados é especificado por "annotation_set_ref_list" abaixo.

annotation_set_ref_list

Referência de parameter_annotations_item

Aparece na seção de dados

Alinhamento: 4 bytes

Nome Formato Descrição
size uint tamanho da lista, em entradas
list annotation_set_ref_item[size] elementos da lista

formato annotation_set_ref_item

Nome Formato Descrição
annotations_off uint deslocamento do início do arquivo até o conjunto de anotações referenciado ou 0 se não houver anotações para esse elemento. O deslocamento, se diferente de zero, precisa ser para um local na seção data. O formato dos dados é especificado por "annotation_set_item" abaixo.

annotation_set_item

Referência de annotations_directory_item, field_annotations_item, method_annotations_item e annotation_set_ref_item

Aparece na seção de dados

Alinhamento: 4 bytes

Nome Formato Descrição
size uint tamanho do conjunto, em entradas
entries annotation_off_item[size] elementos do conjunto. Os elementos precisam ser classificados em ordem crescente, por type_idx.

formato annotation_off_item

Nome Formato Descrição
annotation_off uint deslocamento do início do arquivo para uma anotação. O deslocamento precisa ser para um local na seção data, e o formato dos dados nesse local é especificado por "annotation_item" abaixo.

annotation_item

Referência de annotation_set_item

Aparece na seção de dados

Alinhamento: nenhum (alinhamento de byte)

Nome Formato Descrição
visibilidade ubyte visibilidade pretendida desta anotação (confira abaixo)
annotation encoded_annotation conteúdo da anotação codificada, no formato descrito por "formato encoded_annotation" em "codificação encoded_value" acima.

Valores de visibilidade

Estas são as opções para o campo visibility em um annotation_item:

Nome Valor Descrição
VISIBILITY_BUILD 0x00 destinado a ficar visível apenas no momento da build (por exemplo, durante a compilação de outro código)
VISIBILITY_RUNTIME 0x01 que será visível no momento da execução
VISIBILITY_SYSTEM 0x02 que fica visível no tempo de execução, mas apenas para o sistema (e não para o código do usuário comum)

encoded_array_item

Referência de class_def_item

Aparece na seção de dados

Alinhamento: nenhum (alinhamento de byte)

Nome Formato Descrição
value encoded_array Bytes que representam o valor da matriz codificada, no formato especificado por "Formato encoded_array" em "Codificação encoded_value" acima.

hiddenapi_class_data_item

Esta seção contém dados sobre interfaces restritas usadas por cada classe.

Observação:o recurso de API oculto foi introduzido no Android 10.0 e só é aplicável aos arquivos DEX de classes no caminho da classe de inicialização. A lista de flags descrita abaixo pode ser ampliada nas versões futuras do Android. Para mais informações, consulte Restrições para interfaces que não são SDK.

Nome Formato Descrição
size uint tamanho total da seção
compensações uint[] matriz de deslocamentos indexados por class_idx. Uma entrada de matriz zero no índice class_idx significa que não há dados para esse class_idx ou que todas as flags de API ocultas são zero. Caso contrário, a entrada da matriz não é igual a zero e contém um deslocamento do início da seção para uma matriz de flags de API ocultas para essa class_idx.
flags uleb128[] matrizes concatenadas de flags de API ocultas para cada classe. Os possíveis valores de flag estão descritos na tabela abaixo. As flags são codificadas na mesma ordem em que os campos e métodos são codificados nos dados da classe.

Tipos de flag de restrição:

Nome Valor Descrição
lista de permissões 0 São interfaces que podem ser usadas livremente e são aceitas como parte do Índice de pacote do framework do Android oficialmente documentado.
lista cinza 1 São interfaces externas ao SDK que podem ser usadas independentemente do nível da API de destino do aplicativo.
lista de proibições 2 São interfaces externas ao SDK que não podem ser usadas, independentemente do nível da API de destino do aplicativo. O acesso a uma dessas interfaces causa um erro de execução.
greylist-max-o 3 São interfaces não SDK que podem ser usadas no Android 8.x e versões anteriores, a menos que sejam restritas.
greylist-max-p 4 São interfaces não SDK que podem ser usadas para o Android 9.x, a menos que sejam restritas.
greylist-max-q 5 Interfaces não SDK que podem ser usadas no Android 10.x, a menos que sejam restritas.
greylist-max-r 6 Interfaces não SDK que podem ser usadas no Android 11.x, a menos que sejam restritas.

Anotações do sistema

As anotações do sistema são usadas para representar várias informações reflexivas sobre classes (e métodos e campos). Essas informações geralmente são acessadas apenas indiretamente pelo código do cliente (não do sistema).

As anotações do sistema são representadas em arquivos .dex como anotações com visibilidade definida como VISIBILITY_SYSTEM.

dalvik.annotation.AnnotationDefault

Aparece em métodos em interfaces de anotação

Uma anotação AnnotationDefault é anexada a cada interface de anotação que quer indicar vinculações padrão.

Nome Formato Descrição
value Annotation as vinculações padrão para essa anotação, representadas como uma anotação desse tipo. A anotação não precisa incluir todos os nomes definidos por ela. Os nomes ausentes simplesmente não têm padrões.

dalvik.annotation.EnclosingClass

Aparece nas turmas

Uma anotação EnclosingClass é anexada a cada classe que é definida como um membro de outra classe, por si só, ou é anônima, mas não definida em um corpo de método (por exemplo, uma classe interna sintética). Todas as classes que têm essa anotação também precisam ter uma anotação InnerClass. Além disso, uma classe não pode ter uma anotação EnclosingClass e uma EnclosingMethod.

Nome Formato Descrição
value Classe a classe que tem o escopo lexical mais próximo desta classe

dalvik.annotation.EnclosingMethod

Aparece nas turmas

Uma anotação EnclosingMethod é anexada a cada classe definida dentro do corpo de um método. Todas as classes que têm essa anotação também precisam ter uma anotação InnerClass. Além disso, uma classe não pode ter uma anotação EnclosingClass e uma EnclosingMethod.

Nome Formato Descrição
value Método O método que tem o escopo lexical mais próximo dessa classe

dalvik.annotation.InnerClass

Aparece nas turmas

Uma anotação InnerClass é anexada a cada classe, que é definida no escopo lexical da definição de outra classe. Qualquer classe que tenha essa anotação também precisa ter uma anotação EnclosingClass ou uma EnclosingMethod.

Nome Formato Descrição
nome String o nome simples declarado originalmente dessa classe (sem incluir prefixo de pacote). Se essa classe for anônima, o nome será null.
accessFlags int as flags de acesso declaradas originalmente da classe (que podem ser diferentes das flags efetivas devido a uma incompatibilidade entre os modelos de execução da linguagem de origem e da máquina virtual de destino)

dalvik.annotation.MemberClasses

Aparece nas turmas

Uma anotação MemberClasses é anexada a cada classe que declara classes de membros. Uma classe de membro é uma classe interna direta que tem um nome.

Nome Formato Descrição
value Class[] matriz das classes de membros

dalvik.annotation.MethodParameters

Aparece em métodos

Observação:essa anotação foi adicionada após o Android 7.1. A presença dele em versões anteriores do Android será ignorada.

Uma anotação MethodParameters é opcional e pode ser usada para fornecer metadados de parâmetro, como nomes e modificadores.

A anotação pode ser omitida de um método ou construtor com segurança quando os metadados do parâmetro não são necessários no momento da execução. java.lang.reflect.Parameter.isNamePresent() pode ser usado para verificar se os metadados estão presentes em um parâmetro, e os métodos de reflexão associados, como java.lang.reflect.Parameter.getName(), vão retornar ao comportamento padrão no momento da execução se as informações não estiverem presentes.

Ao incluir metadados de parâmetro, os compiladores precisam incluir informações para classes geradas, como enumerações, já que os metadados de parâmetro incluem se um parâmetro é sintético ou obrigatório.

Uma anotação MethodParameters descreve apenas parâmetros de método individuais. Portanto, os compiladores podem omitir a anotação por completo para construtores e métodos que não têm parâmetros, para fins de tamanho de código e eficiência de execução.

As matrizes documentadas abaixo precisam ter o mesmo tamanho da estrutura dex method_id_item associada ao método. Caso contrário, uma java.lang.reflect.MalformedParametersException será gerada no tempo de execução.

Ou seja: method_id_item.proto_idx -> proto_id_item.parameters_off -> type_list.size precisa ser igual a names().length e accessFlags().length.

Como MethodParameters descreve todos os parâmetros de método formais, mesmo aqueles que não são declarados explicitamente ou implicitamente no código-fonte, o tamanho das matrizes pode ser diferente da assinatura ou de outras informações de metadados que se baseiam apenas em parâmetros explícitos declarados no código-fonte. MethodParameters também não inclui informações sobre parâmetros do receptor de anotação de tipo que não existem na assinatura do método real.

Nome Formato Descrição
nomes String[] Os nomes dos parâmetros formais para o método associado. A matriz não pode ser nula, mas precisa estar vazia se não houver parâmetros formais. Um valor na matriz precisa ser nulo se o parâmetro formal com esse índice não tiver nome.
Se as strings de nome de parâmetro estiverem vazias ou contiverem ".", "?", "[" ou "/", uma java.lang.reflect.MalformedParametersException será gerada no tempo de execução.
accessFlags int[] As flags de acesso dos parâmetros formais para o método associado. A matriz não pode ser nula, mas precisa estar vazia se não houver parâmetros formais.
O valor é uma máscara de bits com os seguintes valores:
  • 0x0010 : final, o parâmetro foi declarado como final
  • 0x1000 : sintética, o parâmetro foi introduzido pelo compilador.
  • 0x8000 : obrigatório, o parâmetro é sintético, mas também é implícito pela especificação de idioma.
Se algum bit for definido fora desse conjunto, uma java.lang.reflect.MalformedParametersException será gerada no momento da execução.

dalvik.annotation.Signature

Aparece em classes, campos e métodos

Uma anotação Signature é anexada a cada classe, campo ou método que é definido em termos de um tipo mais complicado do que o que pode ser representado por um type_id_item. O formato .dex não define o formato para assinaturas. Ele apenas representa as assinaturas que um idioma de origem exige para a implementação bem-sucedida da semântica desse idioma. Por isso, as assinaturas geralmente não são analisadas (ou verificadas) por implementações de máquina virtual. As assinaturas são simplesmente transmitidas para APIs e ferramentas de nível mais alto (como depuradores). Portanto, qualquer uso de uma assinatura precisa ser escrito de modo a não fazer suposições sobre receber apenas assinaturas válidas, protegendo-se explicitamente contra a possibilidade de encontrar uma assinatura sintaticamente inválida.

Como as strings de assinatura tendem a ter muito conteúdo duplicado, uma anotação Signature é definida como uma matriz de strings, em que os elementos duplicados se referem naturalmente aos mesmos dados, e a assinatura é considerada a concatenação de todas as strings na matriz. Não há regras sobre como separar uma assinatura em strings separadas. Isso depende totalmente das ferramentas que geram arquivos .dex.

Nome Formato Descrição
value String[] a assinatura dessa classe ou membro, como uma matriz de strings que será concatenada

dalvik.annotation.Throws

Aparece em métodos

Uma anotação Throws é anexada a cada método que é declarado para gerar um ou mais tipos de exceção.

Nome Formato Descrição
value Class[] a matriz de tipos de exceção gerados