apktool

Outil de rétro-ingénierie d'APK Android. Décode les ressources, le code smali et l'AndroidManifest.xml d'un APK, puis réassemble les APK modifiés. Android APK reverse engineering tool. Decodes APK resources, smali code, and AndroidManifest.xml, then re-assembles modified APKs.

↗ https://apktool.org

Overview

apktool decodes Android APK files into their constituent parts: decompiled smali bytecode, XML resources, AndroidManifest.xml, and assets. It also re-assembles modified smali back into a valid APK. It’s the first step in Android app analysis and tampering.

Decompile (Decode)

Decode an APK

apktool d app.apk

Decode to specific directory

apktool d app.apk -o decoded_app/

Keep original files (don’t disassemble dex)

apktool d app.apk --no-src

Don’t decode resources (faster, keep resources.arsc as-is)

apktool d app.apk --no-res

Force overwrite of output directory

apktool d app.apk -f -o decoded_app/

Match apktool version to APK

apktool d app.apk --frame-path /tmp/frames/

Recompile (Build)

Rebuild modified APK

apktool b decoded_app/

Build to specific output

apktool b decoded_app/ -o modified_app.apk

Sign the rebuilt APK (required for installation) Generate keystore

keytool -genkey -v -keystore my.keystore -alias mykey -keyalg RSA -keysize 2048 -validity 10000

Sign APK

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
  -keystore my.keystore modified_app.apk mykey

Verify signature

jarsigner -verify -verbose -certs modified_app.apk

Alternative: use apksigner

apksigner sign --ks my.keystore --out signed_app.apk modified_app.apk

Key Files After Decoding

decoded_app/
├── AndroidManifest.xml    # Permissions, activities, services, receivers
├── apktool.yml            # apktool metadata
├── res/                   # Resources (layouts, strings, drawables)
│   ├── layout/            # UI XML files
│   ├── values/strings.xml # Hardcoded strings, API keys
│   └── raw/               # Raw assets
├── smali/                 # Dalvik bytecode (smali format)
│   └── com/target/app/    # Package structure → .smali files
└── assets/                # Static assets (certs, configs, databases)

AndroidManifest.xml Analysis

# After decoding, examine permissions and components
cat decoded_app/AndroidManifest.xml | grep -i permission
cat decoded_app/AndroidManifest.xml | grep -i "android:exported"
cat decoded_app/AndroidManifest.xml | grep -i "debuggable"
cat decoded_app/AndroidManifest.xml | grep -i "backup"

Finding Secrets in Smali/Resources

# Search for API keys, passwords, secrets
grep -r "password\|api_key\|secret\|token" decoded_app/res/values/
grep -r "http\|https" decoded_app/res/values/strings.xml
grep -rn "secret\|password\|key" decoded_app/smali/

# Find network endpoints
grep -rn "http[s]\?://" decoded_app/smali/
grep -rn "http[s]\?://" decoded_app/res/

Smali Patching Examples

# Example: bypass certificate pinning
# Find method that checks certificate
# Change conditional branch to always pass

# Before (certificate validation fails → jump to error)
if-nez v0, :cond_fail

# After (always continue, never fail)
if-nez v0, :cond_pass   # or just nop the branch

Tips

  • Use jadx for Java decompilation (more readable than smali); use apktool for rebuilding
  • After patching, always sign before installing — unsigned APKs won’t install
  • Use objection after patching to hook at runtime without modifying the APK
  • Modify AndroidManifest.xml to set android:debuggable="true" for easier debugging
Help / Man page
apktool [options] command [command options]

Commands:
  d / decode         Decode APK
  b / build          Build APK from sources
  if / install-framework  Install framework file

Decode options:
  -f, --force          Force delete destination dir
  -o, --output         Output directory
  --no-src             Don't disassemble dex files
  --no-res             Don't decode resources
  --force-manifest     Decode AndroidManifest.xml regardless
  -r, --no-res         Keep resources.arsc as-is
  --frame-path         Framework directory
  -t, --frame-tag      Framework tag

Build options:
  -f, --force-all      Skip changes detection
  -o, --output         Output APK file
  --frame-path         Framework directory

Vue d’ensemble

apktool décode les fichiers APK Android en leurs éléments constitutifs : bytecode smali décompilé, ressources XML, AndroidManifest.xml et assets. Il réassemble aussi du smali modifié en un APK valide. C’est la première étape de l’analyse et de la modification d’une application Android.

Décompiler (Decode)

# Décoder un APK
apktool d app.apk

# Décoder vers un répertoire spécifique
apktool d app.apk -o decoded_app/

# Garder les fichiers d'origine (ne pas désassembler le dex)
apktool d app.apk --no-src

# Ne pas décoder les ressources (plus rapide, garde resources.arsc tel quel)
apktool d app.apk --no-res

# Forcer l'écrasement du répertoire de sortie
apktool d app.apk -f -o decoded_app/

# Faire correspondre la version d'apktool à l'APK
apktool d app.apk --frame-path /tmp/frames/

Recompiler (Build)

# Reconstruire l'APK modifié
apktool b decoded_app/

# Construire vers une sortie spécifique
apktool b decoded_app/ -o modified_app.apk

Signer l’APK reconstruit (nécessaire pour l’installation). Générer un keystore :

keytool -genkey -v -keystore my.keystore -alias mykey -keyalg RSA -keysize 2048 -validity 10000
# Signer l'APK
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
  -keystore my.keystore modified_app.apk mykey

# Vérifier la signature
jarsigner -verify -verbose -certs modified_app.apk

# Alternative : utiliser apksigner
apksigner sign --ks my.keystore --out signed_app.apk modified_app.apk

Fichiers clés après décodage

decoded_app/
├── AndroidManifest.xml    # Permissions, activités, services, receivers
├── apktool.yml            # Métadonnées apktool
├── res/                   # Ressources (layouts, chaînes, drawables)
│   ├── layout/            # Fichiers XML d'interface
│   ├── values/strings.xml # Chaînes en dur, clés d'API
│   └── raw/               # Assets bruts
├── smali/                 # Bytecode Dalvik (format smali)
│   └── com/target/app/    # Structure du package → fichiers .smali
└── assets/                # Assets statiques (certs, configs, bases de données)

Analyse de l’AndroidManifest.xml

# Après décodage, examiner les permissions et les composants
cat decoded_app/AndroidManifest.xml | grep -i permission
cat decoded_app/AndroidManifest.xml | grep -i "android:exported"
cat decoded_app/AndroidManifest.xml | grep -i "debuggable"
cat decoded_app/AndroidManifest.xml | grep -i "backup"

Trouver des secrets dans le smali/les ressources

# Chercher des clés d'API, mots de passe, secrets
grep -r "password\|api_key\|secret\|token" decoded_app/res/values/
grep -r "http\|https" decoded_app/res/values/strings.xml
grep -rn "secret\|password\|key" decoded_app/smali/

# Trouver les endpoints réseau
grep -rn "http[s]\?://" decoded_app/smali/
grep -rn "http[s]\?://" decoded_app/res/

Exemples de patching smali

# Exemple : contourner le certificate pinning
# Trouver la méthode qui vérifie le certificat
# Changer le branchement conditionnel pour qu'il passe toujours

# Avant (la validation du certificat échoue → saut vers l'erreur)
if-nez v0, :cond_fail

# Après (toujours continuer, ne jamais échouer)
if-nez v0, :cond_pass   # ou simplement nop le branchement

Conseils

  • Utilisez jadx pour la décompilation Java (plus lisible que le smali) ; utilisez apktool pour la reconstruction
  • Après patching, signez toujours avant d’installer : les APK non signés ne s’installent pas
  • Utilisez objection après patching pour hooker à l’exécution sans modifier l’APK
  • Modifiez l’AndroidManifest.xml pour mettre android:debuggable="true" afin de faciliter le débogage
Aide / Page de manuel
apktool [options] command [command options]

Commands:
  d / decode         Decode APK
  b / build          Build APK from sources
  if / install-framework  Install framework file

Decode options:
  -f, --force          Force delete destination dir
  -o, --output         Output directory
  --no-src             Don't disassemble dex files
  --no-res             Don't decode resources
  --force-manifest     Decode AndroidManifest.xml regardless
  -r, --no-res         Keep resources.arsc as-is
  --frame-path         Framework directory
  -t, --frame-tag      Framework tag

Build options:
  -f, --force-all      Skip changes detection
  -o, --output         Output APK file
  --frame-path         Framework directory