Οδηγός Frida
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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Εγκατάσταση
Εγκαταστήστε τα frida tools:
pip install frida-tools
pip install frida
Κατεβάστε και εγκαταστήστε στο android τον frida server (Download the latest release).
Μια εντολή για να επανεκκινήσει το adb σε root mode, να συνδεθεί σε αυτό, να ανεβάσει το frida-server, να δώσει exec permissions και να το τρέξει στο παρασκήνιο:
adb root; adb connect localhost:6000; sleep 1; adb push frida-server /data/local/tmp/; adb shell "chmod 755 /data/local/tmp/frida-server"; adb shell "/data/local/tmp/frida-server &"
Ελέγξτε αν λειτουργεί:
frida-ps -U #List packages and processes
frida-ps -U | grep -i <part_of_the_package_name> #Get all the package name
frida-ui (ελεγκτής Frida βασισμένος σε browser)
frida-ui παρέχει διεπαφή web στο http://127.0.0.1:8000 για να εμφανίζει συσκευές/εφαρμογές και να επισυνάπτει ή να εκκινεί στόχους με scripts (δεν απαιτείται CLI).
- Εγκατάσταση (κλειδώστε την έκδοση του
fridaώστε να ταιριάζει με την έκδοση του device server):
uv tool install frida-ui --with frida==16.7.19
# pipx install frida-ui
# pip install frida-ui
- Εκτέλεση:
frida-ui
frida-ui --host 127.0.0.1 --port 8000 --reload
- Χαρακτηριστικά: ανιχνεύει USB/τοπικές συσκευές, προσθέτει απομακρυσμένους διακομιστές (
192.168.1.x:27042), και υποστηρίζει Attach, Spawn, και Spawn & Run (για να hook πριν από την πρώιμη λογικήonCreate()). - Scripting: ενσωματωμένος επεξεργαστής, drag & drop
.js, import CodeShare, download scripts και session logs. - Remote servers:
./frida-server -l 0.0.0.0:27042 -Dτο εκθέτει στο δίκτυο ώστε το frida-ui να μπορεί να συνδεθεί χωρίς ADB.
Frida server vs. Gadget (root vs. no-root)
Δύο κοινοί τρόποι για να instrument εφαρμογές Android με Frida:
- Frida server (rooted devices): Προώθησε και τρέξε έναν native daemon που σου επιτρέπει να attach σε οποιαδήποτε διεργασία.
- Frida Gadget (no root): Συμπερίλαβε το Frida ως shared library μέσα στο APK και φόρτωσέ το αυτόματα εντός της στοχευμένης διεργασίας.
Frida server (rooted)
# Download the matching frida-server binary for your device's arch
# https://github.com/frida/frida/releases
adb root
adb push frida-server-<ver>-android-<arch> /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server & # run at boot via init/magisk if desired
# From host, list processes and attach
frida-ps -Uai
frida -U -n com.example.app
Frida Gadget (no-root)
- Αποσυμπιέστε το APK, προσθέστε το gadget .so και το config:
- Τοποθετήστε το libfrida-gadget.so στο
lib/<abi>/(π.χ., lib/arm64-v8a/) - Δημιουργήστε assets/frida-gadget.config με τις ρυθμίσεις φόρτωσης των scripts σας
Παράδειγμα frida-gadget.config
{
"interaction": { "type": "script", "path": "/sdcard/ssl-bypass.js" },
"runtime": { "logFile": "/sdcard/frida-gadget.log" }
}
- Αναφορά/φόρτωση του gadget ώστε να αρχικοποιείται νωρίς:
- Πιο εύκολο: Πρόσθεσε ένα μικρό Java stub για System.loadLibrary(“frida-gadget”) στο Application.onCreate(), ή χρησιμοποίησε το native lib loading που υπάρχει ήδη.
- Ξανασυσκευάστε και υπογράψτε το APK, στη συνέχεια εγκαταστήστε:
apktool d app.apk -o app_m
# ... add gadget .so and config ...
apktool b app_m -o app_gadget.apk
uber-apk-signer -a app_gadget.apk -o out_signed
adb install -r out_signed/app_gadget-aligned-debugSigned.apk
- Συνδέστε από το host στη διεργασία gadget:
frida-ps -Uai
frida -U -n com.example.app
Σημειώσεις
- Το Gadget εντοπίζεται από ορισμένες προστασίες· κρατήστε τα ονόματα/διαδρομές διακριτικά και φορτώστε αργά/υπό συνθήκη αν χρειάζεται.
- Σε ενισχυμένες εφαρμογές, προτιμήστε rooted testing με server + late attach, ή συνδυάστε με Magisk/Zygisk hiding.
Έγχυση Frida μέσω JDWP χωρίς root/repackaging (frida-jdwp-loader)
Εάν το APK είναι debuggable (android:debuggable=“true”), μπορείτε να συνδεθείτε μέσω JDWP και να εγχύσετε μια native βιβλιοθήκη σε ένα Java breakpoint. No root και no APK repackaging.
- Repo: https://github.com/frankheat/frida-jdwp-loader
- Απαιτήσεις: ADB, Python 3, USB/Wireless debugging. Η εφαρμογή πρέπει να είναι debuggable (emulator με
ro.debuggable=1, rooted device μεresetprop, ή rebuild manifest).
Γρήγορη εκκίνηση:
git clone https://github.com/frankheat/frida-jdwp-loader.git
cd frida-jdwp-loader
# Inject frida-gadget.so into a debuggable target
python frida-jdwp-loader.py frida -n com.example.myapplication
# Keep the breakpoint thread suspended for early hooks
python frida-jdwp-loader.py frida -n com.example.myapplication -s
# Networkless: run a local agent script via Gadget "script" mode
python frida-jdwp-loader.py frida -n com.example.myapplication -i script -l script.js
Σημειώσεις
- Λειτουργίες: spawn (break at Application.onCreate) ή attach (break at Activity.onStart). Χρησιμοποιήστε
-bγια να ορίσετε μια συγκεκριμένη Java μέθοδο,-gγια να επιλέξετε Gadget έκδοση/διαδρομή,-pγια να επιλέξετε JDWP θύρα. - Λειτουργία ακρόασης: προώθηση του Gadget (default 127.0.0.1:27042) αν χρειαστεί:
adb forward tcp:27042 tcp:27042; στη συνέχειαfrida-ps -H 127.0.0.1:27042. - Αυτό εκμεταλλεύεται το JDWP debugging. Ο κίνδυνος είναι να παραδοθούν debuggable builds ή να εκτεθεί το JDWP.
Αυτοδύναμος agent + ενσωμάτωση Gadget (Frida 17+; αυτοματοποιημένο με Objection)
Το Frida 17 αφαίρεσε τα ενσωματωμένα Java/ObjC bridges από το GumJS. Αν ο agent σας hooks Java, πρέπει να συμπεριλάβετε το Java bridge μέσα στο bundle σας.
- Δημιουργήστε έναν Frida agent (TypeScript) και συμπεριλάβετε το Java bridge
# Scaffolding
frida-create -t agent -o mod
cd mod && npm install
# Install the Java bridge for Frida 17+
npm install frida-java-bridge
# Dev loop (optional live-reload via REPL)
npm run watch
Ελάχιστο Java hook (αναγκάζει τις ρίψεις των ζαριών να είναι 1):
import Java from "frida-java-bridge";
Java.perform(function () {
var dicer = Java.use("org.secuso.privacyfriendlydicer.dicer.Dicer");
dicer.rollDice.implementation = function (numDice: number, numFaces: number) {
return Array(numDice).fill(1);
};
});
Δημιουργήστε ένα ενιαίο bundle για ενσωμάτωση:
npm run build # produces _agent.js via frida-compile
Γρήγορος έλεγχος USB (προαιρετικό):
frida -U -f org.secuso.privacyfriendlydicer -l _agent.js
- Ρύθμισε το Gadget ώστε να φορτώνει αυτόματα το script σου Ο patcher του Objection αναμένει μια Gadget config; όταν χρησιμοποιείς script mode, καθόρισε το on-disk path μέσα στο APK lib dir:
{
"interaction": {
"type": "script",
"path": "libfrida-gadget.script.so"
}
}
- Αυτοματοποιήστε το APK patching με Objection
# Embed Gadget, config, and your compiled agent into the APK; rebuild and sign
objection patchapk -s org.secuso.privacyfriendlydicer.apk \
-c gadget-config.json \
-l mod/_agent.js \
--use-aapt2
Τι κάνει το patchapk (σε υψηλό επίπεδο):
- Εντοπίζει το ABI της συσκευής (π.χ., arm64-v8a) και κατεβάζει το αντίστοιχο Gadget
- Προαιρετικά προσθέτει android.permission.INTERNET όταν χρειάζεται
- Εγχείει έναν στατικό initializer κλάσης που καλεί System.loadLibrary(“frida-gadget”) στην launch activity
- Τοποθετεί τα ακόλουθα κάτω από
lib/<abi>/: - libfrida-gadget.so
- libfrida-gadget.config.so (σειριοποιημένη διαμόρφωση)
- libfrida-gadget.script.so (το _agent.js σας)
Παράδειγμα ενσωματωμένου smali (static initializer):
.method static constructor <clinit>()V
.locals 1
const-string v0, "frida-gadget"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
return-void
.end method
- Επαληθεύστε το repack
apktool d org.secuso.privacyfriendlydicer.apk
apktool d org.secuso.privacyfriendlydicer.objection.apk
# Inspect differences
diff -r org.secuso.privacyfriendlydicer org.secuso.privacyfriendlydicer.objection
Αναμενόμενες αλλαγές:
- AndroidManifest.xml μπορεί να περιέχει
<uses-permission android:name="android.permission.INTERNET"/> - Νέες native libs στο
lib/<abi>/όπως παραπάνω - Το smali της launchable activity περιέχει ένα static
<clinit>που καλεί System.loadLibrary(“frida-gadget”)
- Split APKs
- Patch το base APK (αυτό που δηλώνει την MAIN/LAUNCHER activity)
- Re-sign τα υπόλοιπα splits με το ίδιο key:
objection signapk split1.apk split2.apk ...
- Εγκαταστήστε τα splits μαζί:
adb install-multiple split1.apk split2.apk ...
- Για διανομή, μπορείτε να συγχωνεύσετε τα splits σε ένα μόνο APK με APKEditor, στη συνέχεια align/sign
Αφαίρεση FLAG_SECURE κατά τη διάρκεια της dynamic analysis
Εφαρμογές που καλούν getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE) εμποδίζουν τα screenshots, τις remote displays και ακόμη και τα Android’s recent-task snapshots. Όταν το Freedom Chat επέβαλε αυτό το flag, ο μόνος τρόπος να τεκμηριώσετε τα leaks ήταν να παραποιήσετε το παράθυρο κατά το runtime. Ένα αξιόπιστο μοτίβο είναι:
- Hook every
Windowoverload that can re-apply the flag (setFlags,addFlags,setAttributes) and mask out bit0x00002000(WindowManager.LayoutParams.FLAG_SECURE). - After each activity resumes, schedule a UI-thread call to
clearFlags(FLAG_SECURE)so Dialogs/Fragments created later inherit the unlocked state. - Apps built with React Native / Flutter often create nested windows; hook
android.app.Dialog/android.view.Viewhelpers or walkgetWindow().peekDecorView()if you still see black frames.
Frida hook clearing Window.FLAG_SECURE
```javascript Java.perform(function () { var LayoutParams = Java.use("android.view.WindowManager$LayoutParams"); var FLAG_SECURE = LayoutParams.FLAG_SECURE.value; var Window = Java.use("android.view.Window"); var Activity = Java.use("android.app.Activity");function strip(value) { var masked = value & (~FLAG_SECURE); if (masked !== value) { console.log(“[-] Stripped FLAG_SECURE from 0x” + value.toString(16)); } return masked; }
Window.setFlags.overload(‘int’, ‘int’).implementation = function (flags, mask) { return this.setFlags.call(this, strip(flags), strip(mask)); };
Window.addFlags.implementation = function (flags) { return this.addFlags.call(this, strip(flags)); };
Window.setAttributes.implementation = function (attrs) { attrs.flags.value = strip(attrs.flags.value); return this.setAttributes.call(this, attrs); };
Activity.onResume.implementation = function () { this.onResume(); var self = this; Java.scheduleOnMainThread(function () { try { self.getWindow().clearFlags(FLAG_SECURE); console.log(“[+] Cleared FLAG_SECURE on “ + self.getClass().getName()); } catch (err) { console.log(”[!] clearFlags failed: “ + err); } }); }; });
</details>
Εκτέλεσε το script με `frida -U -f <package> -l disable-flag-secure.js --no-pause`, αλληλεπίδρασε με το UI, και τα screenshots/recordings θα λειτουργήσουν ξανά. Επειδή όλα συμβαίνουν στο UI thread δεν υπάρχει τρεμόπαιγμα, και μπορείς να συνδυάσεις το hook με HTTP Toolkit/Burp για να καταγράψεις την κίνηση που αποκάλυψε το `/channel` PIN leak.
## Δυναμικό DEX dumping / unpacking με clsdumper (Frida)
`clsdumper` είναι ένα Frida-based δυναμικό **DEX/class dumper** που επιβιώνει σε hardened apps συνδυάζοντας ένα anti-Frida pre-stage με native και Java discovery strategies (λειτουργεί ακόμη κι αν `Java.perform()` τερματιστεί). Requirements: Python 3.10+, rooted device με `frida-server` σε λειτουργία, USB ή `--host` TCP connection.
**Εγκατάσταση & γρήγορη χρήση**
```bash
pip install clsdumper
# Attach to a running app
clsdumper com.example.app
# Spawn first (hooks before early loaders)
clsdumper com.example.app --spawn
# Select strategies
clsdumper com.example.app --strategies fart_dump,oat_extract
Επιλογές CLI (πιο χρήσιμες)
target: όνομα πακέτου ή PID.--spawn: spawn αντί για attach.--host <ip>: συνδέεται σε απομακρυσμένο frida-server.--strategies <comma>: περιορίζει/επιλέγει extractors; προεπιλογή είναι όλα εκτόςmmap_hook(ακριβό σε πόρους).--no-scan/--deep-scan: απενεργοποιεί ή επιβραδύνει τη βαθιά σάρωση μνήμης (προσθέτει CDEX scanning).--extract-classes: μετα-επεξεργάζεται τα dumps σε.smaliμέσω androguard.--no-anti-frida: παραλείπει το στάδιο pre-hook bypass.--list/--list-apps: απαριθμεί τις τρέχουσες διεργασίες ή τα εγκατεστημένα πακέτα.
Παράκαμψη anti-instrumentation (φάση 0)
- Κάνει hook σε
sigaction/signalγια να εμποδίσει την καταχώρηση crash/anti-debug handlers. - Σερβίρει φιλτραρισμένο
/proc/self/mapsμέσωmemfd_createγια να κρύψει περιοχές Frida. - Παρακολουθεί
pthread_createγια να εντοπίζει/αχρηστεύει watchdog threads που κυνηγούν τη Frida.
DEX discovery (phases 1–2) — πολλαπλές συμπληρωματικές στρατηγικές με μεταδεδομένα ανά εύρημα + deduplication (agent-side djb2, host-side SHA-256):
- Native (no Java bridge needed):
art_walk(περιηγείται ART Runtime→ClassLinker→DexFile),open_common_hook(hookDexFile::OpenCommon),memory_scan(DEX magic σε αναγνώσιμους χάρτες μνήμης),oat_extract(αναλύει mapped .vdex/.oat),fart_dump(hookDefineClass+ περάσμα στοclass_table_),dexfile_constructor(hook constructors τουOatDexFile),mmap_hook(παρακολουθείmmap/mmap64, απενεργοποιημένο από προεπιλογή για λόγους απόδοσης). - Java (when available):
cookie(διαβάζειmCookieαπό ClassLoaders),classloader_hook(παρακολουθείloadClass,DexClassLoader,InMemoryDexClassLoader).
Διάταξη εξόδου
dump_<target>/
dex/classes_001.dex ...
classes/ # only when --extract-classes
metadata.json # strategy per hit + hashes
Συμβουλή: οι προστατευμένες εφαρμογές συχνά φορτώνουν κώδικα από πολλαπλές πηγές (in-memory payload, vdex/oat, custom loaders). Η εκτέλεση με το προεπιλεγμένο σύνολο multi-strategy μαζί με --spawn μεγιστοποιεί την κάλυψη· ενεργοποιήστε --deep-scan μόνο όταν χρειάζεται για να αποφύγετε επιπτώσεις στην απόδοση.
Οδηγοί
Οδηγός 1
Από: https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1
APK: https://github.com/t0thkr1s/frida-demo/releases
Πηγαίος Κώδικας: https://github.com/t0thkr1s/frida-demo
Ακολούθησε τον σύνδεσμο για να το διαβάσεις.
Οδηγός 2
Από: https://11x256.github.io/Frida-hooking-android-part-2/ (Μέρη 2, 3 & 4)
APKs και Πηγαίος Κώδικας: https://github.com/11x256/frida-android-examples
Ακολούθησε τον σύνδεσμο για να το διαβάσεις.
Οδηγός 3
Από: https://joshspicer.com/android-frida-1
APK: https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk
Ακολούθησε τον σύνδεσμο για να το διαβάσεις.
Μπορείτε να βρείτε περισσότερα Awesome Frida scripts εδώ: https://codeshare.frida.re/
Γρήγορα Παραδείγματα
Κλήση Frida από τη γραμμή εντολών
frida-ps -U
#Basic frida hooking
frida -l disableRoot.js -f owasp.mstg.uncrackable1
#Hooking before starting the app
frida -U --no-pause -l disableRoot.js -f owasp.mstg.uncrackable1
#The --no-pause and -f options allow the app to be spawned automatically,
#frozen so that the instrumentation can occur, and the automatically
#continue execution with our modified code.
Βασικό Python Script
import frida, sys
jscode = open(sys.argv[0]).read()
process = frida.get_usb_device().attach('infosecadventures.fridademo')
script = process.create_script(jscode)
print('[ * ] Running Frida Demo application')
script.load()
sys.stdin.read()
Hooking συναρτήσεων χωρίς παραμέτρους
Κάνε Hook τη συνάρτηση a() της κλάσης sg.vantagepoint.a.c
Java.perform(function () {
rootcheck1.a.overload().implementation = function () {
return false;
};
});
Hook java exit()
var sysexit = Java.use("java.lang.System")
sysexit.exit.overload("int").implementation = function (var_0) {
send("java.lang.System.exit(I)V // We avoid exiting the application :)")
}
Hook MainActivity .onStart() & .onCreate()
var mainactivity = Java.use("sg.vantagepoint.uncrackable1.MainActivity")
mainactivity.onStart.overload().implementation = function () {
send("MainActivity.onStart() HIT!!!")
var ret = this.onStart.overload().call(this)
}
mainactivity.onCreate.overload("android.os.Bundle").implementation = function (
var_0
) {
send("MainActivity.onCreate() HIT!!!")
var ret = this.onCreate.overload("android.os.Bundle").call(this, var_0)
}
Hook android .onCreate()
var activity = Java.use("android.app.Activity")
activity.onCreate.overload("android.os.Bundle").implementation = function (
var_0
) {
send("Activity HIT!!!")
var ret = this.onCreate.overload("android.os.Bundle").call(this, var_0)
}
Hooking συναρτήσεων με παραμέτρους και ανάκτηση της τιμής
Hooking μιας decryption function. Εκτύπωσε την είσοδο, κάλεσε την αρχική συνάρτηση για να decrypt την είσοδο και τελικά εκτύπωσε τα plain δεδομένα:
Hooking μιας decryption function (Java) — εκτύπωση εισόδων/εξόδων
```javascript function getString(data) { var ret = "" for (var i = 0; i < data.length; i++) { ret += data[i].toString() } return ret } var aes_decrypt = Java.use("sg.vantagepoint.a.a") aes_decrypt.a.overload("[B", "[B").implementation = function (var_0, var_1) { send("sg.vantagepoint.a.a.a([B[B)[B doFinal(enc) // AES/ECB/PKCS7Padding") send("Key : " + getString(var_0)) send("Encrypted : " + getString(var_1)) var ret = this.a.overload("[B", "[B").call(this, var_0, var_1) send("Decrypted : " + ret)var flag = “” for (var i = 0; i < ret.length; i++) { flag += String.fromCharCode(ret[i]) } send(“Decrypted flag: “ + flag) return ret //[B }
</details>
### Hooking functions και κλήση τους με την είσοδό μας
Hook μια function που δέχεται ένα string και κάλεσέ την με άλλο string (από [here](https://11x256.github.io/Frida-hooking-android-part-2/))
```javascript
var string_class = Java.use("java.lang.String") // get a JS wrapper for java's String class
my_class.fun.overload("java.lang.String").implementation = function (x) {
//hooking the new function
var my_string = string_class.$new("My TeSt String#####") //creating a new String by using `new` operator
console.log("Original arg: " + x)
var ret = this.fun(my_string) // calling the original function with the new String, and putting its return value in ret variable
console.log("Return value: " + ret)
return ret
}
Λήψη ενός ήδη δημιουργημένου αντικειμένου μιας κλάσης
Αν θέλεις να εξαγάγεις κάποια ιδιότητα (attribute) ενός δημιουργημένου αντικειμένου, μπορείς να χρησιμοποιήσεις αυτό.
Σε αυτό το παράδειγμα θα δεις πώς να πάρεις το αντικείμενο της κλάσης my_activity και πώς να καλέσεις τη συνάρτηση .secret() που θα εκτυπώσει μια ιδιωτική ιδιότητα του αντικειμένου:
Java.choose("com.example.a11x256.frida_test.my_activity", {
onMatch: function (instance) {
//This function will be called for every instance found by frida
console.log("Found instance: " + instance)
console.log("Result of secret func: " + instance.secret())
},
onComplete: function () {},
})
Άλλοι οδηγοί για Frida
- https://github.com/DERE-ad2001/Frida-Labs
- Part 1 of Advanced Frida Usage blog series: IOS Encryption Libraries
Αναφορές
- Build a Repeatable Android Bug Bounty Lab: Emulator vs Magisk, Burp, Frida, and Medusa
- Frida Gadget documentation
- Frida releases (server binaries)
- Objection (SensePost)
- Modding And Distributing Mobile Apps with Frida
- frida-jdwp-loader
- Library injection for debuggable Android apps (blog)
- jdwp-lib-injector (original idea/tool)
- jdwp-shellifier
- “Super secure” MAGA-themed messaging app leaks everyone’s phone number
- Android Frida Hooking: Disabling FLAG_SECURE
- frida-ui
- clsdumper — Android Dynamic Class Dumper
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
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


