Artefactos auxiliares de un APK
1. Qué es y por qué existe
Un APK real tiene mucho más de lo que aparece en cualquier diagrama de anatomía. Junto al
manifiesto, el DEX, resources.arsc, res/ y lib/ conviven decenas —a veces cientos— de
entradas que no encajan en ninguna de esas categorías: metadatos de firma, perfiles de
compilación, descriptores de servicio de Java, ficheros de versión de cada dependencia,
recursos de bibliotecas que se colaron desde su .jar original. En
eu.faircode.email_2318.apk del corpus hay 166 entradas en la raíz o sin categoría, 66
ficheros .version bajo META-INF/ y 8 .kotlin_builtins.
Nada de eso es basura, y casi nada es aleatorio. Cada grupo es la huella de una pieza
concreta de la cadena de construcción: META-INF/*.version significa AndroidX,
DebugProbesKt.bin significa kotlinx-coroutines, assets/dexopt/baseline.prof significa
que alguien se preocupó del arranque. Leer ese inventario da, antes de decompilar nada, el
stack sobre el que está construida la aplicación.
Este documento inventaria y describe esos artefactos, y aclara además una confusión frecuente:
los ficheros que no están dentro del APK pero aparecen cuando se investiga en un
dispositivo —.odex, .vdex, .oat, .art—, qué son y por qué el DEX del APK sigue
siendo la fuente de verdad.
El detalle criptográfico de la firma v1 no está aquí, sino en Esquemas v1, v2 y v3. Aquí solo el inventario y el formato de texto.
2. META-INF/
Es un directorio con nombre reservado que Android hereda del formato JAR de Java. Su contenido se divide en cuatro grupos con orígenes distintos.
| Grupo | Entradas | Lo pone |
|---|---|---|
| Firma v1 | MANIFEST.MF, *.SF, *.RSA / *.DSA / *.EC |
apksigner o jarsigner |
| Metadatos de Java | services/, versions/, *.kotlin_module |
Copiados de los .jar de las dependencias |
| Metadatos de build | com/android/build/gradle/app-metadata.properties, version-control-info.textproto, *.version |
AGP |
| Resto | native-image/, *.properties, licencias |
Las dependencias, sin filtrar |
2.1 MANIFEST.MF
Fichero de texto con la gramática del JAR: una sección principal con atributos globales, una línea en blanco, y luego una sección por entrada con su digest.
manifest-file: main-section newline *individual-section
main-section: version-info newline *main-attribute
individual-section: Name : value newline *perentry-attribute
Dos reglas de formato que muerden a quien lo escriba:
- «No line may be longer than 72 bytes (in UTF-8 encoded form)». Lo que sobra continúa en la línea siguiente empezando por un espacio. Un nombre de fichero largo se parte, y reconstruirlo mal produce un digest que no valida.
- Los nombres de cabecera no se repiten dentro de una sección y su longitud máxima es de 70 bytes.
Contenido real de eu.faircode.email_2318.apk:
Manifest-Version: 1.0
Name: AndroidManifest.xml
SHA-256-Digest: 9EfxvZLEAOD2+jEmNu9nu2+x7C7jpwuyCUIqAfVwyaE=
Name: EmojiReference.txt
SHA-256-Digest: JHTJCDKXj8NxyqaKAY/OGmdtIBtWCKWE/6idHTCEJgU=
Hay una sección Name: por cada entrada del ZIP salvo las del propio META-INF/ que
participan en la firma, con el digest en base64 de su contenido descomprimido.
2.2 *.SF
El fichero de firma. Misma gramática, pero los digests no son de los ficheros: son de las
secciones de MANIFEST.MF. Ese doble nivel es lo que permite verificar la integridad del
propio manifiesto sin recorrer todas las entradas.
Signature-Version: 1.0
Created-By: 1.0 (Android)
SHA-256-Digest-Manifest: m26RkTMb+iMPYOc3UvVskWmTPW4hHW2PVM8noQY+XO0=
X-Android-APK-Signed: 2, 3
Name: AndroidManifest.xml
SHA-256-Digest: Hz4mtPY9Y8CSLhP1DI4kwE7sOn0kD0guSy4cEMCVQC4=
SHA-256-Digest-Manifestcubre elMANIFEST.MFentero. Es la variantex-Digest-Manifestde la especificación JAR.- Cada
Name:lleva el digest de su bloque de texto dentro deMANIFEST.MF, no del fichero. Por eso el valor deAndroidManifest.xmldifiere entre los dos ficheros. X-Android-APK-Signedes una extensión de Android, no del JAR. Declara qué esquemas modernos firman también este APK —aquí, v2 y v3— para que un verificador que los soporte no acepte una degradación a v1 a secas.
2.3 *.RSA, *.DSA, *.EC
El bloque de firma binario: un mensaje PKCS#7/CMS que contiene la firma sobre el .SF y la
cadena de certificados. La especificación JAR reserva:
META-INF/*.SF— fichero de firmaMETA-INF/*.RSA— firma PKCS7 (SHA-256 + RSA)META-INF/*.DSA— firma PKCS7 con DSAMETA-INF/*.EC— firma PKCS7 con ECDSAMETA-INF/SIG-*— firmas con algoritmos no estándar
El nombre base lo elige el firmante y no significa nada: en el corpus aparecen
CIARANG.SF/CIARANG.RSA (F-Droid), 84D3000E.SF/84D3000E.RSA (Termux),
20821372.SF/20821372.RSA (FairEmail) y APKMIRRO.RSA en los contenedores .apkm. El
.SF y el bloque tienen que compartir el nombre base; la extensión declara el algoritmo.
Puede haber más de un juego .SF + bloque: son firmantes distintos sobre el mismo
MANIFEST.MF.
2.4 services/
El mecanismo ServiceLoader de Java: un fichero por interfaz, con el nombre completamente
cualificado de la interfaz como nombre de fichero y las implementaciones dentro, una por
línea. En eu.faircode.email_2318.apk:
META-INF/services/java.nio.charset.spi.CharsetProvider
META-INF/services/java.security.Provider
META-INF/services/javax.mail.Provider
META-INF/services/org.tinylog.provider.LoggingProvider
META-INF/services/d4
META-INF/services/e4
Las dos últimas líneas son el detalle interesante: d4 y e4 son nombres ofuscados por
R8. El renombrado de clases alcanza a los ficheros de services/, porque su nombre es un
nombre de clase. Cuando se ve un META-INF/services/ con nombres de una o dos letras, se está
mirando una aplicación con R8 en modo completo.
2.5 versions/ y los multi-release JAR
META-INF/versions/<N>/ es el mecanismo de multi-release JAR de Java 9 (JEP 238): permite
empaquetar en el mismo archivo una versión alternativa de una clase para cada versión del
runtime. La activación exige un atributo en el manifiesto:
«The manifest entry
Multi-Release: truemust be set to create a Multi-Release JAR File»
En el corpus hay 15 APK con entradas bajo META-INF/versions/, con rutas como
META-INF/versions/9/OSGI-INF/MANIFEST.MF o META-INF/versions/11/…, y ninguno de los 15
lleva Multi-Release en su MANIFEST.MF. Son restos que vienen dentro de los .jar de las
dependencias y que el empaquetador copió sin filtrar.
⚠️ sin verificar: no se ha localizado documentación de AOSP sobre si ART implementa la
resolución multi-release. La observación anterior es del corpus, no de la especificación.
2.6 *.kotlin_module
Un fichero binario por módulo de Kotlin, con el nombre
META-INF/<módulo>_<buildType>.kotlin_module. Contiene los metadatos que el compilador
necesita para resolver funciones y propiedades de nivel superior —las que en el bytecode
viven en una clase sintética FooKt—. Solo lo consume el compilador de Kotlin al enlazar
contra la biblioteca; en tiempo de ejecución es peso muerto dentro de un APK. Su ausencia
rompe la compilación contra esa biblioteca, no su ejecución.
2.7 Metadatos de build
Tres artefactos que AGP escribe y que sirven de huella exacta de la cadena de construcción:
| Entrada | Contenido |
|---|---|
META-INF/com/android/build/gradle/app-metadata.properties |
Versión del formato y del plugin |
META-INF/version-control-info.textproto |
Sistema de control de versiones y commit exacto |
META-INF/<grupo>_<artefacto>.version |
Un fichero por dependencia AndroidX, con su versión |
Contenido real de eu.faircode.email_2318.apk:
appMetadataVersion=1.1
androidGradlePluginVersion=9.2.1
repositories {
system: GIT
local_root_path: "$PROJECT_DIR"
revision: "96852054a5be335f6ea971c338891ec1c97044db"
}
El version-control-info.textproto es el más jugoso de los tres: da el hash de commit
exacto con el que se construyó el APK. En una aplicación de código abierto, eso permite
reproducir la compilación; en una cerrada, es una fuga de información menor pero real.
3. Baseline profiles
3.1 Qué son
Un baseline profile es una lista de métodos y clases que conviene compilar por adelantado,
para que ART no tenga que interpretarlos ni compilarlos con JIT en el primer arranque.
«A Baseline Profile is a Profile Guided Optimization (PGO) mechanism that improves code execution speed by about 30% from the first launch by avoiding interpretation and just-in-time (JIT) compilation steps for included code paths.»
«During installation, ART performs AOT compilation of the methods in the profile, resulting in those methods executing faster.»
Viven en dos entradas fijas del APK:
| Entrada | Qué es |
|---|---|
assets/dexopt/baseline.prof |
El perfil binario en el formato que consume ART |
assets/dexopt/baseline.profm |
Los metadatos que permiten transcodificar el perfil a otra versión del formato |
El .profm existe porque «ART profiles formats aren't forward or backward compatible», así
que profgen empaqueta metadatos con los que androidx.profileinstaller puede convertir el
perfil al formato que espera el dispositivo concreto.
3.2 Formato a alto nivel
Ambos empiezan por una cabecera de 8 bytes: 4 de magia y 4 de versión, ambos terminados en
\0. En eu.faircode.email_2318.apk:
baseline.prof → 7072 6f00 3031 3000 … "pro\0" "010\0"
baseline.profm → 7072 6d00 3030 3200 … "prm\0" "002\0"
que corresponden a las constantes de androidx.profileinstaller:
MAGIC_PROF = new byte[]{'p', 'r', 'o', '\u0000'}
MAGIC_PROFM = new byte[]{'p', 'r', 'm', '\u0000'}
Detrás de la cabecera van unos pocos campos de tamaño y luego un bloque comprimido: los bytes
78 01, cabecera típica de zlib, aparecen en el offset 0x11 de baseline.prof y en el
0x14 de baseline.profm. Dentro, según la documentación del formato en AOSP, hay una lista
de ficheros DEX con su checksum y su clave de perfil, y luego las secciones de clases y de
métodos con sus banderas y sus mapas de bits.
La versión del formato importa y no es estable. AOSP declara hoy:
const uint8_t ProfileCompilationInfo::kProfileMagic[] = { 'p', 'r', 'o', '\0' };
const uint8_t ProfileCompilationInfo::kProfileVersion[] = { '0', '1', '5', '\0' };
const uint8_t ProfileCompilationInfo::kProfileVersionForBootImage[] = { '0', '1', '6', '\0' };
es decir 015, mientras que el fichero del corpus lleva 010. Esa distancia es exactamente
el motivo por el que el .profm va al lado: el perfil que se empaqueta no tiene por qué estar
en el formato del dispositivo que lo va a instalar.
3.3 Cuánto se usa
52 de los 58 APK standalone del corpus llevan las dos entradas —entre ellos FairEmail,
Bitwarden, AnkiDroid, Nextcloud, OpenVPN, StreetComplete y todo el conjunto de Fossify—,
siempre en pareja baseline.prof + baseline.profm. Es hoy la norma, no la excepción.
4. assets/
4.1 Frente a res/
La diferencia es de indexación, no de contenido:
«Files saved in the
assets/directory are not given a resource ID, so you can't reference them through theRclass or from XML resources. Instead, you can query files in theassets/directory like a normal file system and read raw data usingAssetManager.»
«However, if you need access to the original filenames and file hierarchy, consider saving resources in the
assets/directory instead ofres/raw/.»
res/ |
assets/ |
|
|---|---|---|
Indexado en resources.arsc |
Sí | No |
| Identificador | resource ID de 32 bits |
Ninguno: se abre por ruta |
| Nombre y jerarquía original | Se pierden al compilar | Se conservan |
| Se resuelve por configuración | Sí (idioma, densidad, versión) | No |
| API | Resources, R.* |
AssetManager.open() |
Consecuencia para el análisis: al deofuscar recursos se pueden recuperar nombres desde
resources.arsc, porque el nombre está en la tabla
(Tabla de recursos). En assets/ no hay nada que recuperar:
el nombre que hay es el nombre que puso el desarrollador. Si es ilegible, es que se eligió
ilegible.
4.2 Qué se encuentra ahí
En eu.faircode.email_2318.apk, 106 entradas bajo assets/: documentación (ATTRIBUTION.md,
CHANGELOG.md), una guía de configuración traducida a decenas de idiomas (SETUP-es.md,
SETUP-ja.md…) y bases de datos de texto (PublicSuffixDatabase.list). Es el uso normal.
El uso que importa al analizar es el otro. assets/ es un sistema de ficheros opaco dentro
del APK, sin índice y sin restricciones de nombre, y por eso es donde acaban:
- El payload de los packers. Un
packersustituye elDEXoriginal por un stub y guarda el código real cifrado, con frecuencia bajoassets/. Ver Packers y protectores; desempaquetarlos está fuera del alcance de este corpus. - Modelos de aprendizaje automático (
.tflite,.onnx). - Bases de datos precargadas (
.db,.sqlite,.realm). - Bibliotecas nativas escondidas, para saltarse la convención de
lib/<abi>/y cargarlas a mano tras copiarlas a disco. - Claves, certificados y configuración, con frecuencia cifrados de forma trivial.
Un inventario de assets/ por extensión y tamaño es una de las señales más baratas de que
algo no es una aplicación corriente.
5. El lado del dispositivo: dex2oat, .odex, .vdex, .oat, .art
Nada de esta sección está dentro de un APK. Se documenta aquí porque aparece en cuanto se investiga una aplicación instalada y se confunde con el contenido del paquete.
5.1 Qué hace dex2oat
dex2oat es el compilador de ART: «takes an APK file and generates one or more compilation
artifact files that the runtime loads». Se ejecuta en el dispositivo al instalar y, según la
política, también en segundo plano.
| Artefacto | Contenido, según AOSP |
|---|---|
.vdex |
«Contains some additional metadata to speed up verification, sometimes along with the uncompressed DEX code of the APK» |
.odex |
«Contains AOT-compiled code for methods in the APK» |
.art |
«Contains ART internal representations of some strings and classes listed in the APK, used to speed up app startup» |
El .oat es el formato de contenedor del código compilado; desde Android 8 la copia del DEX
original vive en el .vdex y el .odex contiene solo el código nativo.
5.2 Filtros de compilación
Lo que se compila depende del compiler filter:
| Filtro | Qué hace |
|---|---|
verify |
«Runs only DEX code verification (no AOT compilation)» |
quicken |
(Android 11 o anterior) Verifica y optimiza algunas instrucciones DEX para el intérprete |
speed |
«Runs DEX code verification and AOT-compiles all methods» |
speed-profile |
Verifica, compila AOT los métodos del perfil y optimiza la carga de sus clases |
speed-profile es el que consume el baseline profile de la sección 3.
5.3 Dónde viven
El comentario del código de AOSP que construye la ruta:
// The odex file name is formed by replacing the dex_location extension with
// .odex and inserting an oat/<isa> directory. For example:
// location = /foo/bar/baz.jar
// odex_location = /foo/bar/oat/<isa>/baz.odex
Aplicado a una aplicación instalada, el base.apk vive bajo /data/app/…/<paquete>-…/ y sus
artefactos aparecen en oat/<isa>/ al lado, con <isa> la arquitectura (arm64, arm,
x86_64).
⚠️ no ejecutado localmente: adb no está en el PATH de esta máquina, así que no se ha
listado el directorio en un dispositivo real. La forma de la ruta procede del código de AOSP
citado; el prefijo exacto bajo /data/app/ varía por versión de Android y lleva sufijos
aleatorios desde Android 10.
5.4 Por qué el DEX del APK sigue siendo la fuente de verdad
Tres razones, y conviene tenerlas claras antes de perder tiempo con un .odex:
- Son derivados y regenerables. Todo lo que hay en
oat/sale del APK. Borrarlo hace que el sistema lo reconstruya. - Son específicos del dispositivo. Dependen de la arquitectura, de la versión de
ARTy del perfil de uso de ese usuario. Dos dispositivos con el mismo APK producen.odexdistintos. - El formato no es estable ni está especificado como contrato público. Cambia entre versiones de Android, y ninguna herramienta del ecosistema lo trata como formato de entrada de primera clase.
La única situación en la que el .vdex importa de verdad es cuando el APK no contiene el
DEX que se ejecuta: aplicaciones de sistema entregadas ya compiladas, o un packer que genera
el DEX real en ejecución. En ambos casos se está haciendo análisis dinámico, no estático, y
eso es otro documento.
5.5 Perfiles en la nube
Junto al baseline profile que el desarrollador empaqueta, Play distribuye perfiles agregados
del uso real:
«Cloud Profiles offer an additional form of PGO—aggregated by Google Play Store and distributed for install time compilation—together with Baseline Profiles. While Cloud Profiles are driven by real-world user interactions with the app, they take several hours to days after an update to be distributed […] Cloud Profiles only support Android devices running Android 9 (API level 28) or higher, and only scale well for apps that have a sufficiently large user base.»
Para el análisis del APK esto es irrelevante —el perfil no viaja dentro— pero explica por qué el mismo APK puede tener rendimientos distintos según cuándo se instale.
6. Otros artefactos que aparecen en APK reales
Cada uno es la firma de una pieza del stack. Todos verificados en el corpus.
| Entrada | Qué es | Qué delata |
|---|---|---|
stamp-cert-sha256 |
32 bytes: el SHA-256 del certificado del source stamp |
APK distribuido por Google Play. Su bloque compañero en el APK Signing Block es V2_SOURCE_STAMP_BLOCK_ID = 0x6dff800d |
DebugProbesKt.bin |
Clase precompilada de kotlinx-coroutines-debug |
Uso de corrutinas de Kotlin. Presente en más de 25 APK del corpus |
kotlin/*.kotlin_builtins |
Descriptores binarios de los tipos base de Kotlin | Que la aplicación es Kotlin y que el empaquetador no filtró la biblioteca estándar |
kotlin-tooling-metadata.json |
Metadatos del plugin de Kotlin: versión y targets | Versión exacta del compilador de Kotlin |
okhttp3/internal/publicsuffix/publicsuffixes.gz |
Lista de sufijos públicos que OkHttp usa para las cookies | Uso de OkHttp, y con él Retrofit en la mayoría de los casos |
META-INF/native-image/… |
Configuración de GraalVM que traen Netty y jansi | Dependencias de servidor arrastradas a una aplicación móvil |
androidsupportmultidexversion.txt |
Marca de la biblioteca multidex de soporte |
minSdk bajo con más de 65.536 métodos |
firebase-*, com/google/firebase/… |
Recursos y metadatos de los SDK de Firebase | Analítica, notificaciones o Crashlytics |
En org.videolan.vlc_13070108.apk conviven en la raíz DebugProbesKt.bin,
kotlin-tooling-metadata.json, androidsupportmultidexversion.txt, car-app-api.level,
árboles enteros de org/bouncycastle/ con sus ficheros de mensajes traducidos, y —el caso
más llamativo— org/fusesource/jansi/internal/native/Mac/arm64/libjansi.jnilib y
org/fusesource/jansi/internal/native/Windows/x86_64/jansi.dll: binarios de macOS y de
Windows dentro de un APK de Android, arrastrados desde el .jar de jansi y completamente
inertes.
Cómo se lee esto: un artefacto en un sitio donde no puede ejecutarse indica que el
empaquetador copió un .jar entero sin filtrar. No es un problema de seguridad, es tamaño
desperdiciado y una pista muy fiable sobre la disciplina del proyecto.
7. Receta: inventario comentado por categorías
Ejecutado el 12 de agosto de 2026 con unzip y awk del sistema.
CORPUS=~/corpus-apk
unzip -l $CORPUS/org.videolan.vlc_13070108.apk | awk '
NR>3 && NF>=4 { p=$4
if (p ~ /^-+$/ || p=="") next
if (p=="AndroidManifest.xml") k="01 manifiesto"
else if (p ~ /^classes[0-9]*\.dex$/) k="02 codigo DEX"
else if (p=="resources.arsc") k="03 tabla de recursos"
else if (p ~ /^res\//) k="04 res/"
else if (p ~ /^assets\/dexopt\//) k="05 baseline profile"
else if (p ~ /^assets\//) k="06 assets/"
else if (p ~ /^lib\//) k="07 lib/"
else if (p ~ /^META-INF\/(MANIFEST\.MF|.*\.(SF|RSA|DSA|EC))$/) k="08 META-INF firma v1"
else if (p ~ /^META-INF\/services\//) k="09 META-INF services/"
else if (p ~ /^META-INF\/versions\//) k="10 META-INF versions/"
else if (p ~ /\.kotlin_module$/) k="11 kotlin_module"
else if (p ~ /^META-INF\/.*\.version$/) k="12 META-INF .version"
else if (p ~ /^META-INF\//) k="13 META-INF otros"
else if (p ~ /^kotlin\//) k="14 kotlin/ builtins"
else if (p ~ /^okhttp3\//) k="15 okhttp3/"
else k="99 raiz y otros"
c[k]++ }
END { for (k in c) printf "%-24s %6d\n", k, c[k] }' | sort
01 manifiesto 1
02 codigo DEX 6
03 tabla de recursos 1
04 res/ 2424
05 baseline profile 2
06 assets/ 115
07 lib/ 4
08 META-INF firma v1 3
09 META-INF services/ 7
13 META-INF otros 21
14 kotlin/ builtins 8
15 okhttp3/ 2
99 raiz y otros 24
Se lee así: seis classes*.dex (multidex a lo grande), firma v1 presente, dos ficheros de
baseline profile, ocho kotlin_builtins y okhttp3/ — Kotlin más OkHttp —, y 24 entradas
sin clasificar en la raíz que son las que hay que mirar a mano. La categoría 99 es la
interesante: es donde se esconde lo que no sigue ninguna convención.
Y el desglose de esa categoría, que es el que da la huella del stack:
unzip -l $CORPUS/org.videolan.vlc_13070108.apk | awk '{print $4}' \
| grep -vE "^(AndroidManifest.xml|classes[0-9]*\.dex|resources\.arsc|res/|assets/|lib/|META-INF/|kotlin/|okhttp3/|Name|----)" \
| grep -v "^$" | head -10
DebugProbesKt.bin
androidsupportmultidexversion.txt
car-app-api.level
custom.config.conf
custom.config.yaml
debug/AndroidManifest.xml
dev/AndroidManifest.xml
kotlin-tooling-metadata.json
org/bouncycastle/pkix/CertPathReviewerMessages.properties
org/bouncycastle/pkix/CertPathReviewerMessages_de.properties
debug/AndroidManifest.xml y dev/AndroidManifest.xml son, además, un hallazgo por sí solos:
manifiestos de otras variantes de compilación que acabaron dentro del APK de release.
Fuentes
- JAR File Specification — Oracle — https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html
Consultado el 12 de agosto de 2026. De aquí salen la gramática de
MANIFEST.MF, el límite de 72 bytes por línea y su continuación, los atributosx-Digest-Manifestyx-Digest, y la lista de nombres reservados deMETA-INF/de las secciones 2.1 a 2.4. - JEP 238: Multi-Release JAR Files — OpenJDK — https://openjdk.org/jeps/238
Consultado el 12 de agosto de 2026. De aquí sale el requisito del atributo
Multi-Release: truey la estructuraMETA-INF/versions/<N>/de la sección 2.5. - Baseline Profiles overview — Android Developers — https://developer.android.com/topic/performance/baselineprofiles/overview
Consultado el 12 de agosto de 2026. De aquí salen la definición de
baseline profile, la rutaassets/dexopt/baseline.prof, la descripción de la compilación AOT en instalación de la sección 3.1 y la cita completa sobre Cloud Profiles de la sección 5.5. - AOSP —
art/libprofile/profile/profile_compilation_info.cc— https://android.googlesource.com/platform/art/+/refs/heads/main/libprofile/profile/profile_compilation_info.cc Consultado el 12 de agosto de 2026. De aquí salenkProfileMagic,kProfileVersionykProfileVersionForBootImage, y la descripción de las secciones del fichero de perfil de la sección 3.2. - AOSP —
frameworks/support/profileinstaller/.../ProfileTranscoder.java— https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/profileinstaller/profileinstaller/src/main/java/androidx/profileinstaller/ProfileTranscoder.java Consultado el 12 de agosto de 2026. De aquí salenMAGIC_PROFyMAGIC_PROFMde la sección 3.2, que confirman la magiaprm\0observada en el corpus. - App resources overview — Android Developers — https://developer.android.com/guide/topics/resources/providing-resources
Consultado el 12 de agosto de 2026. De aquí salen las dos citas sobre
assets/frente ares/raw/y la ausencia deresource IDde la sección 4.1. - Configure ART — Android Open Source Project — https://source.android.com/docs/core/runtime/configure
Consultado el 12 de agosto de 2026. De aquí salen la descripción de
dex2oat, el contenido de.vdex,.odexy.art, y la tabla de filtros de compilación de las secciones 5.1 y 5.2. - AOSP —
art/runtime/oat/oat_file_assistant.cc— https://android.googlesource.com/platform/art/+/refs/heads/main/runtime/oat/oat_file_assistant.cc Consultado el 12 de agosto de 2026. De aquí sale el comentario que documenta la rutaoat/<isa>/de la sección 5.3. - AOSP —
tools/apksig/.../stamp/SourceStampConstants.java— https://android.googlesource.com/platform/tools/apksig/+/refs/heads/main/src/main/java/com/android/apksig/internal/apk/stamp/SourceStampConstants.java Consultado el 12 de agosto de 2026. De aquí salen el nombre de entradastamp-cert-sha256y los identificadores de bloque0x2b09189e(v1) y0x6dff800d(v2) de la sección 6. - kotlinx-metadata-jvm — JetBrains/kotlin — https://github.com/JetBrains/kotlin/blob/master/libraries/kotlinx-metadata/jvm/ReadMe.md
Consultado el 12 de agosto de 2026. De aquí sale que
.kotlin_modulees el contenedor de metadatos de módulo de Kotlin de la sección 2.6. No se ha localizado una especificación del formato binario, solo la API de lectura y escritura. - Corpus de verificación — 5,9 GB, 86 contenedores y 717 APK: 58 sueltos de F-Droid y 659
dentro de contenedores de splits.
Medido el 12 de agosto de 2026. De aquí salen todos los contenidos reales citados
—
MANIFEST.MF,.SF,services/,app-metadata.properties,version-control-info.textproto, las magias debaseline.profy.profm, los 32 bytes destamp-cert-sha256—, el recuento de 15 APK conMETA-INF/versions/sinMulti-Releasede la sección 2.5, la tabla de la sección 6 y ambas salidas de la sección 7.