Reverse engineering d'une APK Android
Une APK est une archive ZIP. Tout son contenu est extractible sans outil spécialisé — les ressources, le manifest et le code compilé sont présents à plat dans l’archive. La difficulté réside dans le fait que le code et certains fichiers XML sont sous forme binaire, pas lisibles directement.
Extraction brute
Section titled “Extraction brute”unzip app.apk -d apk_extracted/L’arborescence extraite :
apk_extracted/├── AndroidManifest.xml # configuration de l'app (binaire, illisible à ce stade)├── classes.dex # code compilé Dalvik (DEX), illisible├── classes2.dex # code DEX supplémentaire (si présent)├── assets/ # fichiers bruts embarqués (JSON, JS, bases de données…)├── res/ # ressources (layouts XML, images, couleurs…)│ └── values/│ └── strings.xml # chaînes de l'app (souvent des infos utiles)├── lib/ # bibliothèques natives (.so) par architecture└── META-INF/ # signature et certificatsCe qu’on cherche à ce stade
Section titled “Ce qu’on cherche à ce stade”Les fichiers dans assets/ et res/ sont lisibles directement :
# Chercher des URLs, clés API ou tokens dans les ressourcesgrep -r "http" apk_extracted/assets/grep -r "api_key\|secret\|token\|password" apk_extracted/res/values/strings.xml
# Lister les fichiers de configuration embarquésfind apk_extracted/assets/ -name "*.json" -o -name "*.xml" -o -name "*.db"Décompiler avec apktool
Section titled “Décompiler avec apktool”apktool décode les fichiers XML binaires (manifest, layouts) et convertit le code DEX en smali — une représentation assembleur lisible.
apktool d app.apk -o apk_decoded/AndroidManifest.xml décodé
Section titled “AndroidManifest.xml décodé”Le manifest contient les informations de configuration de l’application :
cat apk_decoded/AndroidManifest.xmlCe qu’on y cherche :
<!-- Permissions déclarées — identifier les accès réseau, stockage, caméra… --><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.READ_CONTACTS" />
<!-- Activities exportées — points d'entrée accessibles sans authentification --><activity android:name=".AdminActivity" android:exported="true" />
<!-- Métadonnées — souvent des clés API de services tiers --><meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" />Strings de l’application
Section titled “Strings de l’application”cat apk_decoded/res/values/strings.xmlContient les chaînes de caractères de l’interface, mais aussi parfois des URLs d’endpoints, des clés de configuration ou des identifiants codés en dur.
Décompiler en Java avec JADX
Section titled “Décompiler en Java avec JADX”JADX décompile directement le code DEX en Java lisible, sans passer par le smali. C’est l’outil le plus efficace pour comprendre la logique applicative.
Installation
Section titled “Installation”# Via le binaire releases GitHub (skylot/jadx)wget https://github.com/skylot/jadx/releases/latest/download/jadx-1.5.0.zipunzip jadx-1.5.0.zip -d jadx/Utilisation en ligne de commande
Section titled “Utilisation en ligne de commande”# Décompiler en Java dans un répertoire de sortiejadx -d jadx_output/ app.apk
# Décompiler uniquement les ressources (plus rapide)jadx --no-src -d jadx_output/ app.apkInterface graphique
Section titled “Interface graphique”jadx-gui app.apkJADX-GUI permet de naviguer dans les classes, rechercher des chaînes et suivre les appels de méthodes.
Ce qu’on cherche dans le code Java
Section titled “Ce qu’on cherche dans le code Java”# Credentials et clés codés en durgrep -r "password\|secret\|apiKey\|token\|api_key" jadx_output/sources/ --include="*.java"
# URLs d'API backendgrep -r "http\|https\|retrofit\|OkHttp" jadx_output/sources/ --include="*.java"
# Logique d'authentificationgrep -r "login\|auth\|jwt\|sha\|md5\|encrypt" jadx_output/sources/ --include="*.java" -lCas React Native : bytecode Hermes
Section titled “Cas React Native : bytecode Hermes”Les applications React Native compilées avec le moteur Hermes livrent leur code JavaScript sous forme de bytecode binaire. Le fichier index.android.bundle dans assets/ n’est pas du JavaScript lisible.
Identifier le format
Section titled “Identifier le format”file assets/index.android.bundleassets/index.android.bundle: Hermes JavaScript bytecode, version 96Un cat ou strings ne retourne que des fragments textuels sans la logique du code. Il faut désassembler le bytecode.
Désassembler avec hermes-dec
Section titled “Désassembler avec hermes-dec”hbctool (l’outil historique) n’est plus maintenu pour les versions récentes de Hermes. Utiliser hermes-dec à la place (https://github.com/P1sec/hermes-dec).
Mise en place de l’environnement Python sous WSL :
sudo apt update && sudo apt install python3 python3-venv python3-full -y
# Créer un environnement virtuel isolépython3 -m venv ~/ctf_envsource ~/ctf_env/bin/activateInstallation de hermes-dec :
pip install hermes-decDésassemblage :
hbc-disassemble assets/index.android.bundle output_hbc/La sortie contient le bytecode désassemblé. Les chaînes de caractères (URLs, clés, noms de variables) sont directement lisibles dans les tables de constantes.
Décompilation vers du JavaScript : hermes-dec propose aussi une décompilation partielle vers JS pour certaines versions de bytecode :
hbc-decompile assets/index.android.bundle output.jsCe qu’on cherche dans le bundle React Native
Section titled “Ce qu’on cherche dans le bundle React Native”# Après désassemblage, chercher dans la sortie textegrep -iE "(api|url|endpoint|secret|key|token|password)" output_hbc/*.hasm
# Ou directement via strings sur le bundle (résultats partiels mais rapides)strings assets/index.android.bundle | grep -iE "(https?://|api_key|secret|token)"Workflow complet
Section titled “Workflow complet”1. Extraire l'APK unzip app.apk -d apk_extracted/
2. Lire les ressources brutes grep -r "api\|key\|secret\|token" apk_extracted/assets/ apk_extracted/res/
3. Décoder le manifest et les XML apktool d app.apk -o apk_decoded/ cat apk_decoded/AndroidManifest.xml
4. Décompiler en Java jadx -d jadx_output/ app.apk grep -r "password\|secret" jadx_output/sources/
5. Si React Native — vérifier le type du bundle file apk_extracted/assets/index.android.bundle
6. Si Hermes bytecode — désassembler source ~/ctf_env/bin/activate hbc-disassemble assets/index.android.bundle output_hbc/ grep -iE "(api|secret|token)" output_hbc/*.hasmÀ retenir
Section titled “À retenir”L’extraction brute (unzip) donne immédiatement accès aux ressources et révèle parfois des secrets sans décompilation. apktool rend le manifest lisible et donne accès aux chaînes de l’interface. JADX expose la logique applicative en Java. Pour les applications React Native avec Hermes, il faut une étape supplémentaire de désassemblage du bytecode — strings ne suffit pas à lire la logique du code.