Reversing Native Libraries
Reading time: 7 minutes
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.
For further information check: https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html
Android apps podem usar native libraries, tipicamente escritas em C ou C++, para tarefas que exigem desempenho. Criadores de malware também abusam dessas bibliotecas porque ELF shared objects ainda são mais difíceis de decompilar que byte-code DEX/OAT.
Esta página foca em workflows práticos e melhorias de tooling recentes (2023-2025) que tornam o reversing de arquivos .so
do Android mais fácil.
Quick triage-workflow for a freshly pulled libfoo.so
- Extract the library
# From an installed application
adb shell "run-as <pkg> cat lib/arm64-v8a/libfoo.so" > libfoo.so
# Or from the APK (zip)
unzip -j target.apk "lib/*/libfoo.so" -d extracted_libs/
- Identify architecture & protections
file libfoo.so # arm64 or arm32 / x86
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO, etc.
checksec --file libfoo.so # (peda/pwntools)
- List exported symbols & JNI bindings
readelf -s libfoo.so | grep ' Java_' # dynamic-linked JNI
strings libfoo.so | grep -i "RegisterNatives" -n # static-registered JNI
- Load in a decompiler (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) and run auto-analysis. Newer Ghidra versions introduced an AArch64 decompiler that recognises PAC/BTI stubs and MTE tags, greatly improving analysis of libraries built with the Android 14 NDK.
- Decide on static vs dynamic reversing: stripped, obfuscated code often needs instrumentation (Frida, ptrace/gdbserver, LLDB).
Dynamic Instrumentation (Frida ≥ 16)
Frida’s 16-series trouxe várias melhorias específicas para Android que ajudam quando o alvo usa otimizações modernas do Clang/LLD:
thumb-relocator
agora pode hook tiny ARM/Thumb functions geradas pelo alinhamento agressivo do LLD (--icf=all
).- A enumeração e rebind de ELF import slots funciona no Android, permitindo patching por módulo com
dlopen()
/dlsym()
quando hooks inline são rejeitados. - Java hooking foi corrigido para o novo ART quick-entrypoint usado quando apps são compilados com
--enable-optimizations
no Android 14.
Example: enumerating all functions registered through RegisterNatives
and dumping their addresses at runtime:
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 will work out of the box on PAC/BTI-enabled devices (Pixel 8/Android 14+) as long as you use frida-server 16.2 or later – earlier versions failed to locate o preenchimento para inline hooks.
Telemetria JNI local ao processo via .so pré-carregado (SoTap)
Quando uma instrumentação completa é overkill ou bloqueada, você ainda pode obter visibilidade em nível nativo pré-carregando um pequeno logger dentro do processo alvo. SoTap é uma biblioteca nativa Android leve (.so) que registra o comportamento em tempo de execução de outras bibliotecas JNI (.so) dentro do mesmo processo do app (não é necessário root).
Principais propriedades:
- Inicializa cedo e observa interações JNI/native dentro do processo que a carrega.
- Persiste logs usando múltiplos caminhos graváveis com fallback gracioso para Logcat quando o armazenamento está restrito.
- Personalizável no código-fonte: edite sotap.c para estender/ajustar o que é registrado e recompile por ABI.
Configuração (reempacotar o APK):
- Coloque o build ABI apropriado dentro do APK para que o loader possa resolver libsotap.so:
- lib/arm64-v8a/libsotap.so (for arm64)
- lib/armeabi-v7a/libsotap.so (for arm32)
- Garanta que o SoTap seja carregado antes de outras libs JNI. Injete uma chamada cedo (por exemplo, inicializador estático da subclasse Application ou onCreate) para que o logger seja inicializado primeiro. Exemplo de trecho Smali:
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
- Recompile/assine/instale, execute o app e então colete os logs.
Caminhos de log (verificados em ordem):
/data/user/0/%s/files/sotap.log
/data/data/%s/files/sotap.log
/sdcard/Android/data/%s/files/sotap.log
/sdcard/Download/sotap-%s.log
# If all fail: fallback to Logcat only
Notas e solução de problemas:
- O alinhamento de ABI é obrigatório. Uma incompatibilidade causará UnsatisfiedLinkError e o logger não será carregado.
- Restrições de armazenamento são comuns no Android moderno; se gravações de arquivo falharem, SoTap ainda emitirá via Logcat.
- Comportamento/verbosidade deve ser personalizado; reconstrua a partir do código-fonte após editar sotap.c.
Essa abordagem é útil para triagem de malware e depuração JNI, onde observar fluxos de chamadas nativas desde o início do processo é crítico, mas root/ganchos em todo o sistema não estão disponíveis.
Vulnerabilidades recentes que valem a pena procurar em APKs
Year | CVE | Affected library | Notes |
---|---|---|---|
2023 | CVE-2023-4863 | libwebp ≤ 1.3.1 | Heap buffer overflow alcançável a partir de código nativo que decodifica imagens WebP. Vários apps Android empacotam versões vulneráveis. Quando você encontrar um libwebp.so dentro de um APK, verifique sua versão e tente exploração ou correção. |
2024 | Multiple | OpenSSL 3.x series | Várias questões de segurança de memória e padding-oracle. Muitos bundles Flutter & ReactNative incluem seu próprio libcrypto.so . |
Quando você identificar arquivos .so
de third-party dentro de um APK, sempre confira seu hash contra advisories upstream. SCA (Software Composition Analysis) é incomum em mobile, então builds vulneráveis e desatualizados são comuns.
Tendências de Anti-Reversing & Hardening (Android 13-15)
- Pointer Authentication (PAC) & Branch Target Identification (BTI): Android 14 habilita PAC/BTI em system libraries em silicon ARMv8.3+ suportado. Decompiladores agora mostram pseudo-instruções relacionadas a PAC; para análise dinâmica o Frida injeta trampolines após remover o PAC, mas seus trampolines customizados devem chamar
pacda
/autibsp
quando necessário. - MTE & Scudo hardened allocator: a marcação de memória (memory-tagging) é opt-in, mas muitos apps compatíveis com Play-Integrity são buildados com
-fsanitize=memtag
; usesetprop arm64.memtag.dump 1
maisadb shell am start ...
para capturar tag faults. - LLVM Obfuscator (opaque predicates, control-flow flattening): packers comerciais (ex.: Bangcle, SecNeo) protegem cada vez mais código native, não apenas Java; espere fluxo de controle falso e blobs de strings criptografadas em
.rodata
.
Resources
- Learning ARM Assembly: Azeria Labs – ARM Assembly Basics
- JNI & NDK Documentation: Oracle JNI Spec · Android JNI Tips · NDK Guides
- Debugging Native Libraries: Debug Android Native Libraries Using JEB Decompiler
References
- Changelog do Frida 16.x (Android hooking, tiny-function relocation) – frida.re/news
- Aviso NVD para overflow de
libwebp
CVE-2023-4863 – nvd.nist.gov - SoTap: Lightweight in-app JNI (.so) behavior logger – github.com/RezaArbabBot/SoTap
- SoTap Releases – github.com/RezaArbabBot/SoTap/releases
- How to work with SoTap? – t.me/ForYouTillEnd/13
tip
Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)
Aprenda e pratique Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporte o HackTricks
- Confira os planos de assinatura!
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe truques de hacking enviando PRs para o HackTricks e HackTricks Cloud repositórios do github.