8.5 KiB
Reversing Native Libraries
{{#include ../../banners/hacktricks-training.md}}
Za više informacija pogledajte: https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html
Android aplikacije mogu koristiti native libraries, obično napisane u C ili C++, za zadatke osetljive na performanse. Autori malware-a takođe zloupotrebljavaju ove libraries jer su ELF shared objects i dalje teže za dekompajliranje od DEX/OAT byte-code.
Ova stranica se fokusira na praktične tokove rada i skorašnja poboljšanja alata (2023–2025) koja olakšavaju reversing Android .so
fajlova.
Brzi trijažni tok za sveže izvučen 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. Novije Ghidra verzije uvele su AArch64 dekompajler koji prepoznaje PAC/BTI stubove i MTE tagove, značajno poboljšavajući analizu biblioteka izgrađenih sa Android 14 NDK.
- Decide on static vs dynamic reversing: stripped, obfuscated code often needs instrumentation (Frida, ptrace/gdbserver, LLDB).
Dynamic Instrumentation (Frida ≥ 16)
Frida serija 16 donela je nekoliko Android-specifičnih poboljšanja koja pomažu kada meta koristi moderne Clang/LLD optimizacije:
thumb-relocator
sada može hook-ovati male ARM/Thumb funkcije generisane agresivnim poravnanjem LLD (--icf=all
).- Enumerisanje i rebinding ELF import slots radi na Androidu, omogućavajući per-module
dlopen()
/dlsym()
patching kada inline hooks budu odbijeni. - Java hooking je ispravljen za novi ART quick-entrypoint koji se koristi kada su aplikacije kompajlirane sa
--enable-optimizations
na Android 14.
Primer: enumerisanje svih funkcija registrovanih preko RegisterNatives
i dumpovanje njihovih adresa u runtime-u:
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 će raditi odmah na PAC/BTI-enabled uređajima (Pixel 8/Android 14+) sve dok koristite frida-server 16.2 ili noviji – ranije verzije nisu uspevale da lociraju padding za inline hooks.
Process-local JNI telemetry via preloaded .so (SoTap)
Kada je puna instrumentacija preterana ili blokirana, i dalje možete dobiti vidljivost na nivou native tako što ćete prethodno učitati mali logger unutar ciljnog procesa. SoTap je lagana Android native (.so) biblioteka koja beleži runtime ponašanje drugih JNI (.so) biblioteka unutar istog app procesa (nije potreban root).
Ključna svojstva:
- Inicijalizuje se rano i posmatra JNI/native interakcije unutar procesa koji je učitava.
- Upisuje logove u više upisivih putanja sa automatskim prelaskom na Logcat kada je skladište ograničeno.
- Mogućnost prilagođavanja izvora: izmenite sotap.c da proširite/prilagodite šta se loguje i ponovo izgradite za svaku ABI.
Podešavanje (prepakovanje APK-a):
- Dodajte odgovarajući ABI build u APK tako da loader može da locira libsotap.so:
- lib/arm64-v8a/libsotap.so (for arm64)
- lib/armeabi-v7a/libsotap.so (for arm32)
- Obezbedite da se SoTap učita pre ostalih JNI biblioteka. Injektujte poziv rano (npr. u statičkom inicijalizatoru Application podklase ili u onCreate) tako da se logger inicijalizuje prvi. Smali snippet primer:
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
- Ponovo izgradite/potpišite/instalirajte, pokrenite aplikaciju, pa prikupite logove.
Putanje za logove (proveravaju se redom):
/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
Napomene i rešavanje problema:
- ABI poravnanje je obavezno. Neusklađenost će izazvati UnsatisfiedLinkError i logger se neće učitati.
- Ograničenja skladištenja su česta na modernim Android uređajima; ako upisi u fajl zakažu, SoTap će i dalje emitovati putem Logcat.
- Ponašanje/verbosnost je predviđena za prilagođavanje; nakon izmena u sotap.c ponovo izgradite iz izvornog koda.
Ovaj pristup je koristan za malware triage i JNI debugging u slučajevima kada je ključno posmatrati tokove native poziva od pokretanja procesa, ali root/system-wide hooks nisu dostupni.
See also: in‑memory native code execution via JNI
Uobičajen obrazac napada je preuzimanje sirovog shellcode bloba tokom izvršavanja i njegovo direktno izvršavanje iz memorije preko JNI bridge-a (bez ELF fajla na disku). Detalji i ready‑to‑use JNI snippet ovde:
{{#ref}} in-memory-jni-shellcode-execution.md {{#endref}}
Nedavne ranjivosti koje vredi tražiti u APK-ovima
Year | CVE | Affected library | Notes |
---|---|---|---|
2023 | CVE-2023-4863 | libwebp ≤ 1.3.1 |
Heap buffer overflow koji se može aktivirati iz native code koja dekodira WebP slike. Nekoliko Android aplikacija uključuje ranjive verzije. Kada vidite libwebp.so u APK-u, proverite njegovu verziju i pokušajte eksploataciju ili zakrpu. |
2024 | Multiple | OpenSSL 3.x series | Više memory-safety i padding-oracle problema. Mnogi Flutter & ReactNative bundli sadrže sopstveni libcrypto.so . |
Kada u APK-u primetite third-party .so
fajlove, uvek uporedite njihov hash sa upstream advisories. SCA (Software Composition Analysis) je neuobičajena na mobilnim platformama, pa su zastarele ranjive verzije raširene.
Anti-Reversing & Hardening trends (Android 13-15)
- Pointer Authentication (PAC) & Branch Target Identification (BTI): Android 14 omogućava PAC/BTI u system libraries na podržanom ARMv8.3+ silicijumu. Decompiler-i sada prikazuju PAC‐povezane pseudo-instrukcije; za dinamičku analizu Frida ubrizgava trampoline posle uklanjanja PAC, ali vaši prilagođeni trampolini treba da pozivaju
pacda
/autibsp
kada je potrebno. - MTE & Scudo hardened allocator: memory-tagging je opt-in, ali mnoge Play-Integrity aware aplikacije se grade sa
-fsanitize=memtag
; koristitesetprop arm64.memtag.dump 1
plusadb shell am start ...
da biste zabeležili tag faults. - LLVM Obfuscator (opaque predicates, control-flow flattening): komercijalni packeri (npr., Bangcle, SecNeo) sve više štite native code, ne samo Java; očekujte lažne control-flow i enkriptovane string blobe u
.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
Reference
- Frida 16.x change-log (Android hooking, tiny-function relocation) – frida.re/news
- NVD advisory for
libwebp
overflow 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
- CoRPhone — JNI memory-only execution pattern and packaging
{{#include ../../banners/hacktricks-training.md}}