mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
148 lines
8.5 KiB
Markdown
148 lines
8.5 KiB
Markdown
# Reversing Native Libraries
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|
||
|
||
|
||
**Więcej informacji:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
|
||
|
||
Aplikacje Android mogą używać natywnych bibliotek, zwykle napisanych w C lub C++, do zadań krytycznych pod względem wydajności. Malware creators również nadużywają tych bibliotek, ponieważ ELF shared objects wciąż trudniej zdekompilować niż DEX/OAT byte-code.
|
||
Ta strona koncentruje się na *praktycznych* przepływach pracy i *niedawnych* usprawnieniach narzędzi (2023–2025), które ułatwiają reversing Android `.so` files.
|
||
|
||
---
|
||
|
||
### Szybki triage — przepływ pracy dla świeżo pobranego `libfoo.so`
|
||
|
||
1. **Wyodrębnij bibliotekę**
|
||
```bash
|
||
# 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/
|
||
```
|
||
2. **Zidentyfikuj architekturę i zabezpieczenia**
|
||
```bash
|
||
file libfoo.so # arm64 or arm32 / x86
|
||
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO, etc.
|
||
checksec --file libfoo.so # (peda/pwntools)
|
||
```
|
||
3. **Wypisz eksportowane symbole i powiązania JNI**
|
||
```bash
|
||
readelf -s libfoo.so | grep ' Java_' # dynamic-linked JNI
|
||
strings libfoo.so | grep -i "RegisterNatives" -n # static-registered JNI
|
||
```
|
||
4. **Wczytaj do dekompilera** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) i uruchom automatyczną analizę.
|
||
Nowsze wersje Ghidra wprowadziły dekompiler AArch64, który rozpoznaje PAC/BTI stubs i MTE tags, znacznie poprawiając analizę bibliotek skompilowanych przy użyciu Android 14 NDK.
|
||
5. **Zdecyduj o static vs dynamic reversing:** stripped, obfuscated code often needs *instrumentation* (Frida, ptrace/gdbserver, LLDB).
|
||
|
||
---
|
||
|
||
### Dynamic Instrumentation (Frida ≥ 16)
|
||
|
||
Frida’s 16-series brought several Android-specific improvements that help when the target uses modern Clang/LLD optimisations:
|
||
|
||
* `thumb-relocator` can now *hook tiny ARM/Thumb functions* generated by LLD’s aggressive alignment (`--icf=all`).
|
||
* Enumerating and rebinding *ELF import slots* works on Android, enabling per-module `dlopen()`/`dlsym()` patching when inline hooks are rejected.
|
||
* Java hooking was fixed for the new **ART quick-entrypoint** used when apps are compiled with `--enable-optimizations` on Android 14.
|
||
|
||
Przykład: enumerating all functions registered through `RegisterNatives` and dumping their addresses at runtime:
|
||
```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 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 padding for inline hooks.
|
||
|
||
### Lokalna telemetria JNI w procesie przez preładowane .so (SoTap)
|
||
|
||
Gdy pełna instrumentacja jest przesadą lub zablokowana, nadal możesz uzyskać widoczność na poziomie natywnym przez wstępne załadowanie małego loggera wewnątrz docelowego procesu. SoTap to lekka natywna biblioteka Android (.so), która loguje zachowanie w czasie wykonywania innych bibliotek JNI (.so) w tym samym procesie aplikacji (nie wymaga uprawnień root).
|
||
|
||
Kluczowe właściwości:
|
||
- Inicjalizuje się wcześnie i obserwuje JNI/native interactions wewnątrz procesu, który ją ładuje.
|
||
- Przechowuje logi przy użyciu wielu zapisywalnych ścieżek z zapasowym przejściem do Logcat, gdy pamięć jest ograniczona.
|
||
- Możliwość modyfikacji źródła: edytuj sotap.c, aby rozszerzyć/dostosować, co jest logowane, i przebuduj dla każdego ABI.
|
||
|
||
Setup (repack the APK):
|
||
1) Wstaw odpowiednią kompilację ABI do APK, aby loader mógł rozwiązać libsotap.so:
|
||
- lib/arm64-v8a/libsotap.so (dla arm64)
|
||
- lib/armeabi-v7a/libsotap.so (dla arm32)
|
||
2) Upewnij się, że SoTap ładuje się przed innymi bibliotekami JNI. Wstrzyknij wywołanie wcześnie (np. Application subclass static initializer lub onCreate), aby logger został zainicjalizowany pierwszy. Smali snippet example:
|
||
```smali
|
||
const-string v0, "sotap"
|
||
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
|
||
```
|
||
3) Przebuduj/podpisz/zainstaluj, uruchom aplikację, a następnie zbierz logi.
|
||
|
||
Log paths (checked in order):
|
||
```
|
||
/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
|
||
```
|
||
Notes and troubleshooting:
|
||
- ABI alignment is mandatory. A mismatch will raise UnsatisfiedLinkError and the logger won’t load.
|
||
- Storage constraints are common on modern Android; if file writes fail, SoTap will still emit via Logcat.
|
||
- Behavior/verbosity is intended to be customized; rebuild from source after editing sotap.c.
|
||
|
||
This approach is useful for malware triage and JNI debugging where observing native call flows from process start is critical but root/system-wide hooks aren’t available.
|
||
|
||
---
|
||
|
||
### Zobacz także: in‑memory native code execution via JNI
|
||
|
||
A common attack pattern is to download a raw shellcode blob at runtime and execute it directly from memory through a JNI bridge (no on‑disk ELF). Details and ready‑to‑use JNI snippet here:
|
||
|
||
{{#ref}}
|
||
in-memory-jni-shellcode-execution.md
|
||
{{#endref}}
|
||
|
||
---
|
||
|
||
### Recent vulnerabilities worth hunting for in APKs
|
||
|
||
| Rok | CVE | Biblioteka dotknięta | Uwagi |
|
||
|------|-----|------------------|-------|
|
||
|2023|CVE-2023-4863|`libwebp` ≤ 1.3.1|Heap buffer overflow reachable from native code that decodes WebP images. Several Android apps bundle vulnerable versions. When you see a `libwebp.so` inside an APK, check its version and attempt exploitation or patching.| |
|
||
|2024|Multiple|OpenSSL 3.x series|Several memory-safety and padding-oracle issues. Many Flutter & ReactNative bundles ship their own `libcrypto.so`.|
|
||
|
||
When you spot *third-party* `.so` files inside an APK, always cross-check their hash against upstream advisories. SCA (Software Composition Analysis) is uncommon on mobile, so outdated vulnerable builds are rampant.
|
||
|
||
---
|
||
|
||
### Anti-Reversing & Hardening trends (Android 13-15)
|
||
|
||
* **Pointer Authentication (PAC) & Branch Target Identification (BTI):** Android 14 enables PAC/BTI in system libraries on supported ARMv8.3+ silicon. Decompilers now display PAC‐related pseudo-instructions; for dynamic analysis Frida injects trampolines *after* stripping PAC, but your custom trampolines should call `pacda`/`autibsp` where necessary.
|
||
* **MTE & Scudo hardened allocator:** memory-tagging is opt-in but many Play-Integrity aware apps build with `-fsanitize=memtag`; use `setprop arm64.memtag.dump 1` plus `adb shell am start ...` to capture tag faults.
|
||
* **LLVM Obfuscator (opaque predicates, control-flow flattening):** commercial packers (e.g., Bangcle, SecNeo) increasingly protect *native* code, not only Java; expect bogus control-flow and encrypted string blobs in `.rodata`.
|
||
|
||
---
|
||
|
||
### Resources
|
||
|
||
- **Learning ARM Assembly:** [Azeria Labs – ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/)
|
||
- **JNI & NDK Documentation:** [Oracle JNI Spec](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html) · [Android JNI Tips](https://developer.android.com/training/articles/perf-jni) · [NDK Guides](https://developer.android.com/ndk/guides/)
|
||
- **Debugging Native Libraries:** [Debug Android Native Libraries Using JEB Decompiler](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
|
||
|
||
### References
|
||
|
||
- Frida 16.x change-log (Android hooking, tiny-function relocation) – [frida.re/news](https://frida.re/news/)
|
||
- NVD advisory for `libwebp` overflow CVE-2023-4863 – [nvd.nist.gov](https://nvd.nist.gov/vuln/detail/CVE-2023-4863)
|
||
- SoTap: Lightweight in-app JNI (.so) behavior logger – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
|
||
- SoTap Releases – [github.com/RezaArbabBot/SoTap/releases](https://github.com/RezaArbabBot/SoTap/releases)
|
||
- How to work with SoTap? – [t.me/ForYouTillEnd/13](https://t.me/ForYouTillEnd/13)
|
||
- [CoRPhone — JNI memory-only execution pattern and packaging](https://github.com/0xdevil/corphone)
|
||
|
||
{{#include ../../banners/hacktricks-training.md}}
|