Reversing Native Libraries

Reading time: 8 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Για περισσότερες πληροφορίες δείτε: https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html

Android apps can use native libraries, typically written in C or C++, for performance-critical tasks. Οι δημιουργοί malware επίσης καταχρώνται αυτές τις βιβλιοθήκες επειδή τα ELF shared objects παραμένουν πιο δύσκολα στο decompile από το DEX/OAT byte-code. Αυτή η σελίδα επικεντρώνεται σε πρακτικές ροές εργασίας και πρόσφατες βελτιώσεις εργαλείων (2023-2025) που κάνουν το reversing Android .so αρχείων πιο εύκολο.


Quick triage-workflow for a freshly pulled libfoo.so

  1. Extract the library
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/
  1. Identify architecture & protections
bash
file libfoo.so        # arm64 or arm32 / x86
readelf -h libfoo.so  # OS ABI, PIE, NX, RELRO, etc.
checksec --file libfoo.so  # (peda/pwntools)
  1. List exported symbols & JNI bindings
bash
readelf -s libfoo.so | grep ' Java_'     # dynamic-linked JNI
strings libfoo.so   | grep -i "RegisterNatives" -n   # static-registered JNI
  1. Load in a decompiler (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) and run auto-analysis. Οι νεότερες εκδόσεις του Ghidra εισήγαγαν έναν AArch64 decompiler που αναγνωρίζει PAC/BTI stubs και MTE tags, βελτιώνοντας σημαντικά την ανάλυση βιβλιοθηκών που έχουν χτιστεί με το Android 14 NDK.
  2. Decide on static vs dynamic reversing: stripped, obfuscated code often needs instrumentation (Frida, ptrace/gdbserver, LLDB).

Dynamic Instrumentation (Frida ≥ 16)

Η σειρά 16 του Frida έφερε αρκετές βελτιώσεις ειδικές για Android που βοηθούν όταν ο στόχος χρησιμοποιεί σύγχρονες βελτιστοποιήσεις Clang/LLD:

  • 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.

Παράδειγμα: 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.

Τοπική στη διεργασία τηλεμετρία JNI μέσω προφορτωμένης .so (SoTap)

Όταν η πλήρης instrumentation είναι υπερβολική ή μπλοκαρισμένη, μπορείτε ακόμα να αποκτήσετε ορατότητα σε επίπεδο native φορτώνοντας προληπτικά έναν μικρό logger μέσα στη στοχευόμενη διεργασία. Το SoTap είναι μια ελαφριά Android native (.so) βιβλιοθήκη που καταγράφει τη συμπεριφορά κατά το runtime άλλων JNI (.so) βιβλιοθηκών εντός της ίδιας διεργασίας της εφαρμογής (δεν απαιτείται root).

Key properties:

  • Εκκινεί νωρίς και παρατηρεί τις JNI/native αλληλεπιδράσεις μέσα στη διεργασία που το φορτώνει.
  • Διατηρεί τα logs χρησιμοποιώντας πολλαπλές εγγράψιμες διαδρομές με ομαλή εναλλακτική λύση σε Logcat όταν η αποθήκευση είναι περιορισμένη.
  • Προσαρμόσιμο σε επίπεδο πηγαίου κώδικα: επεξεργαστείτε το sotap.c για να επεκτείνετε/προσαρμόσετε τι καταγράφεται και αναδημιουργήστε ανά ABI.

Setup (repack the APK):

  1. Drop the proper ABI build into the APK so the loader can resolve libsotap.so:
  • lib/arm64-v8a/libsotap.so (for arm64)
  • lib/armeabi-v7a/libsotap.so (for arm32)
  1. Ensure SoTap loads before other JNI libs. Inject a call early (e.g., Application subclass static initializer or onCreate) so the logger is initialized first. Smali snippet example:
smali
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
  1. Rebuild/sign/install, run the app, then collect logs.

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

Σημειώσεις και αντιμετώπιση προβλημάτων:

  • Η στοίχιση ABI είναι υποχρεωτική. Μια ασυμφωνία θα προκαλέσει UnsatisfiedLinkError και ο logger δεν θα φορτωθεί.
  • Οι περιορισμοί αποθήκευσης είναι συνηθισμένοι σε σύγχρονα Android· αν η εγγραφή αρχείων αποτύχει, το SoTap θα συνεχίσει να εκδίδει μέσω Logcat.
  • Η συμπεριφορά/λεπτομέρεια εξόδου προορίζεται για προσαρμογή· ανασυνθέστε από τον πηγαίο κώδικα μετά την επεξεργασία του sotap.c.

Αυτή η προσέγγιση είναι χρήσιμη για την αξιολόγηση malware και το debugging του JNI, όπου η παρατήρηση των native ροών κλήσεων από την εκκίνηση της διεργασίας είναι κρίσιμη αλλά δεν υπάρχουν root/system-wide hooks.


Δείτε επίσης: in‑memory native code execution via JNI

Ένα συνηθισμένο μοτίβο επίθεσης είναι να κατεβάσει ένα raw shellcode blob κατά το runtime και να το εκτελέσει απευθείας από τη μνήμη μέσω μιας JNI bridge (χωρίς on‑disk ELF). Λεπτομέρειες και έτοιμο προς χρήση JNI snippet εδώ:

In Memory Jni Shellcode Execution


Πρόσφατες ευπάθειες που αξίζει να αναζητήσετε σε APKs

YearCVEAffected libraryNotes
2023CVE-2023-4863libwebp ≤ 1.3.1Heap buffer overflow προσβάσιμο από native κώδικα που αποκωδικοποιεί εικόνες WebP. Πολλές εφαρμογές Android ενσωματώνουν ευπαθείς εκδόσεις. Όταν δείτε ένα libwebp.so μέσα σε ένα APK, ελέγξτε την έκδοσή του και δοκιμάστε εκμετάλλευση ή επιδιόρθωση.
2024MultipleOpenSSL 3.x seriesΠολλά ζητήματα ασφάλειας μνήμης και padding-oracle. Πολλά πακέτα Flutter & ReactNative περιλαμβάνουν το δικό τους libcrypto.so.

Όταν εντοπίσετε third-party .so αρχεία μέσα σε ένα APK, πάντα ελέγχετε το hash τους έναντι upstream advisories. SCA (Software Composition Analysis) είναι ασυνήθιστο στο mobile, οπότε παρωχημένα ευπαθή builds είναι διαδεδομένα.


  • Pointer Authentication (PAC) & Branch Target Identification (BTI): Το Android 14 ενεργοποιεί PAC/BTI στις system libraries σε υποστηριζόμενα ARMv8.3+ silicon. Οι decompilers πλέον εμφανίζουν pseudo-εντολές σχετικές με PAC· για dynamic analysis, το Frida εγχέει trampolines after stripping PAC, αλλά τα custom trampolines σας θα πρέπει να καλούν pacda/autibsp όπου χρειάζεται.
  • MTE & Scudo hardened allocator: Το memory-tagging είναι opt-in αλλά πολλές εφαρμογές που σέβονται Play-Integrity κατασκευάζονται με -fsanitize=memtag; χρησιμοποιήστε setprop arm64.memtag.dump 1 μαζί με adb shell am start ... για να συλλάβετε tag faults.
  • LLVM Obfuscator (opaque predicates, control-flow flattening): Οι commercial packers (π.χ., Bangcle, SecNeo) προστατεύουν ολοένα και περισσότερο τον native κώδικα, όχι μόνο Java· αναμένετε ψευδή control-flow και κρυπτογραφημένα string blobs στο .rodata.

Resources

Αναφορές

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks