Translated ['src/mobile-pentesting/android-app-pentesting/reversing-nati

This commit is contained in:
Translator 2025-07-10 21:34:40 +00:00
parent 97e9d3c909
commit 4c3aff0469

View File

@ -4,41 +4,92 @@
**Pour plus d'informations, consultez :** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
Les applications Android peuvent utiliser des bibliothèques natives, généralement écrites en C ou C++, pour des tâches critiques en termes de performance. Les créateurs de logiciels malveillants utilisent également ces bibliothèques, car elles sont plus difficiles à rétroconcevoir que le bytecode DEX. La section met l'accent sur les compétences en rétro-ingénierie adaptées à Android, plutôt que d'enseigner les langages d'assemblage. Des versions ARM et x86 des bibliothèques sont fournies pour la compatibilité.
Les applications Android peuvent utiliser des bibliothèques natives, généralement écrites en C ou C++, pour des tâches critiques en termes de performance. Les créateurs de logiciels malveillants abusent également de ces bibliothèques car les objets partagés ELF sont encore plus difficiles à décompiler que le code byte DEX/OAT. Cette page se concentre sur des workflows *pratiques* et des améliorations d'outils *récentes* (2023-2025) qui facilitent le reverse engineering des fichiers `.so` Android.
### Points Clés :
---
- **Bibliothèques Natives dans les Applications Android :**
- Utilisées pour des tâches intensives en performance.
- Écrites en C ou C++, rendant la rétro-ingénierie difficile.
- Trouvées au format `.so` (objet partagé), similaire aux binaires Linux.
- Les créateurs de logiciels malveillants préfèrent le code natif pour rendre l'analyse plus difficile.
- **Java Native Interface (JNI) & Android NDK :**
- JNI permet d'implémenter des méthodes Java en code natif.
- NDK est un ensemble d'outils spécifique à Android pour écrire du code natif.
- JNI et NDK relient le code Java (ou Kotlin) aux bibliothèques natives.
- **Chargement et Exécution des Bibliothèques :**
- Les bibliothèques sont chargées en mémoire à l'aide de `System.loadLibrary` ou `System.load`.
- JNI_OnLoad est exécuté lors du chargement de la bibliothèque.
- Les méthodes natives déclarées en Java se lient aux fonctions natives, permettant l'exécution.
- **Liaison des Méthodes Java aux Fonctions Natives :**
- **Liaison Dynamique :** Les noms de fonctions dans les bibliothèques natives correspondent à un modèle spécifique, permettant une liaison automatique.
- **Liaison Statique :** Utilise `RegisterNatives` pour la liaison, offrant flexibilité dans le nommage et la structure des fonctions.
- **Outils et Techniques de Rétro-Ingénierie :**
- Des outils comme Ghidra et IDA Pro aident à analyser les bibliothèques natives.
- `JNIEnv` est crucial pour comprendre les fonctions et interactions JNI.
- Des exercices sont fournis pour pratiquer le chargement de bibliothèques, la liaison de méthodes et l'identification de fonctions natives.
### Workflow de triage rapide pour un `libfoo.so` fraîchement extrait
### Ressources :
1. **Extraire la bibliothèque**
```bash
# À partir d'une application installée
adb shell "run-as <pkg> cat lib/arm64-v8a/libfoo.so" > libfoo.so
# Ou à partir de l'APK (zip)
unzip -j target.apk "lib/*/libfoo.so" -d extracted_libs/
```
2. **Identifier l'architecture et les protections**
```bash
file libfoo.so # arm64 ou arm32 / x86
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO, etc.
checksec --file libfoo.so # (peda/pwntools)
```
3. **Lister les symboles exportés et les liaisons JNI**
```bash
readelf -s libfoo.so | grep ' Java_' # JNI lié dynamiquement
strings libfoo.so | grep -i "RegisterNatives" -n # JNI enregistré statiquement
```
4. **Charger dans un décompilateur** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper ou Cutter/Rizin) et exécuter l'analyse automatique. Les versions plus récentes de Ghidra ont introduit un décompilateur AArch64 qui reconnaît les stubs PAC/BTI et les balises MTE, améliorant considérablement l'analyse des bibliothèques construites avec le NDK Android 14.
5. **Décider entre reverse engineering statique et dynamique :** le code obfusqué et supprimé nécessite souvent une *instrumentation* (Frida, ptrace/gdbserver, LLDB).
- **Apprendre l'Assemblage ARM :**
- Suggéré pour une compréhension plus approfondie de l'architecture sous-jacente.
- [ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/) d'Azeria Labs est recommandé.
- **Documentation JNI & NDK :**
- [Spécification JNI d'Oracle](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html)
- [Conseils JNI d'Android](https://developer.android.com/training/articles/perf-jni)
- [Commencer avec le NDK](https://developer.android.com/ndk/guides/)
- **Débogage des Bibliothèques Natives :**
- [Déboguer les Bibliothèques Natives Android en Utilisant JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
---
### Instrumentation Dynamique (Frida ≥ 16)
La série 16 de Frida a apporté plusieurs améliorations spécifiques à Android qui aident lorsque la cible utilise des optimisations modernes Clang/LLD :
* `thumb-relocator` peut maintenant *hooker de petites fonctions ARM/Thumb* générées par l'alignement agressif de LLD (`--icf=all`).
* L'énumération et le rebinding des *slots d'importation ELF* fonctionnent sur Android, permettant le patching `dlopen()`/`dlsym()` par module lorsque les hooks en ligne sont rejetés.
* Le hooking Java a été corrigé pour le nouveau **point d'entrée rapide ART** utilisé lorsque les applications sont compilées avec `--enable-optimizations` sur Android 14.
Exemple : énumérer toutes les fonctions enregistrées via `RegisterNatives` et extraire leurs adresses à l'exécution :
```javascript
Java.perform(function () {
var Runtime = Java.use('java.lang.Runtime');
var register = Module.findExportByName(null, 'RegisterNatives');
Interceptor.attach(register, {
onEnter(args) {
var envPtr = args[0];
var clazz = Java.cast(args[1], Java.use('java.lang.Class'));
var methods = args[2];
var count = args[3].toInt32();
console.log('[+] RegisterNatives on ' + clazz.getName() + ' -> ' + count + ' methods');
// iterate & dump (JNI nativeMethod struct: name, sig, fnPtr)
}
});
});
```
Frida fonctionnera dès la sortie de la boîte sur les appareils activés PAC/BTI (Pixel 8/Android 14+) tant que vous utilisez frida-server 16.2 ou une version ultérieure les versions antérieures n'ont pas réussi à localiser le padding pour les hooks en ligne. citeturn5search2turn5search0
---
### Vulnérabilités récentes à rechercher dans les APK
| Année | CVE | Bibliothèque affectée | Remarques |
|------|-----|------------------|-------|
|2023|CVE-2023-4863|`libwebp` ≤ 1.3.1|Dépassement de tampon de tas accessible depuis le code natif qui décode les images WebP. Plusieurs applications Android regroupent des versions vulnérables. Lorsque vous voyez un `libwebp.so` à l'intérieur d'un APK, vérifiez sa version et tentez l'exploitation ou le patching.| citeturn2search0|
|2024|Multiple|Série OpenSSL 3.x|Plusieurs problèmes de sécurité mémoire et d'oracle de padding. De nombreux bundles Flutter & ReactNative expédient leur propre `libcrypto.so`.|
Lorsque vous repérez des fichiers `.so` *tiers* à l'intérieur d'un APK, vérifiez toujours leur hash par rapport aux avis en amont. L'analyse de composition logicielle (SCA) est rare sur mobile, donc les builds vulnérables obsolètes sont répandus.
---
### Tendances Anti-Reversing & Hardening (Android 13-15)
* **Authentification de pointeur (PAC) & Identification de cible de branche (BTI) :** Android 14 active PAC/BTI dans les bibliothèques système sur les silicons ARMv8.3+ pris en charge. Les décompilateurs affichent désormais des pseudo-instructions liées à PAC ; pour l'analyse dynamique, Frida injecte des trampolines *après* avoir supprimé PAC, mais vos trampolines personnalisés doivent appeler `pacda`/`autibsp` si nécessaire.
* **MTE & Allocateur durci Scudo :** le tagging de mémoire est opt-in mais de nombreuses applications conscientes de Play-Integrity sont construites avec `-fsanitize=memtag` ; utilisez `setprop arm64.memtag.dump 1` plus `adb shell am start ...` pour capturer les fautes de tag.
* **Obfuscateur LLVM (prédicats opaques, aplatissement de flux de contrôle) :** les packers commerciaux (par exemple, Bangcle, SecNeo) protègent de plus en plus le code *natif*, pas seulement Java ; attendez-vous à des flux de contrôle faux et à des blobs de chaînes chiffrées dans `.rodata`.
---
### Ressources
- **Apprendre l'assemblage ARM :** [Azeria Labs Notions de base sur l'assemblage ARM](https://azeria-labs.com/writing-arm-assembly-part-1/)
- **Documentation JNI & NDK :** [Spécification JNI d'Oracle](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html) · [Conseils JNI Android](https://developer.android.com/training/articles/perf-jni) · [Guides NDK](https://developer.android.com/ndk/guides/)
- **Débogage des bibliothèques natives :** [Déboguer les bibliothèques natives Android à l'aide de JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
### Références
- Journal des modifications de Frida 16.x (hooking Android, relocation de fonction minuscule) [frida.re/news](https://frida.re/news/) citeturn5search0
- Avis NVD pour le dépassement de `libwebp` CVE-2023-4863 [nvd.nist.gov](https://nvd.nist.gov/vuln/detail/CVE-2023-4863) citeturn2search0
{{#include ../../banners/hacktricks-training.md}}