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 UI στο 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()). - Δημιουργία scripts: ενσωματωμένος επεξεργαστής, drag & drop
.js, εισαγωγή CodeShare, λήψη scripts και αρχείων καταγραφής συνεδρίας. - Απομακρυσμένοι διακομιστές:
./frida-server -l 0.0.0.0:27042 -Dτο εκθέτει στο δίκτυο ώστε το frida-ui να μπορεί να συνδεθεί χωρίς ADB.
Frida server vs. Gadget (root vs. no-root)
Δύο συνηθισμένοι τρόποι για να κάνετε instrumentation εφαρμογών Android με το Frida:
- Frida server (rooted devices): Προωθείτε και εκτελείτε έναν εγγενή daemon που σας επιτρέπει να συνδεθείτε σε οποιαδήποτε διεργασία.
- 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 με τις ρυθμίσεις φόρτωσης των script σας
Παράδειγμα 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 βιβλιοθηκών.
- Επανασυσκευάστε και υπογράψτε το 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
- Attach από host στη διαδικασία gadget:
frida-ps -Uai
frida -U -n com.example.app
Σημειώσεις
- Gadget εντοπίζεται από κάποιες προστασίες· κράτα τα names/paths διακριτικά και φόρτωσέ τα αργά/υπό όρους αν χρειάζεται.
- Σε hardened apps, προτίμησε rooted testing με server + late attach, ή συνδύασέ το με Magisk/Zygisk hiding.
JDWP-based Frida injection without root/repackaging (frida-jdwp-loader)
Αν το APK είναι debuggable (android:debuggable=“true”), μπορείς να κάνεις attach μέσω JDWP και να εγχύσεις μια native βιβλιοθήκη σε ένα Java breakpoint. Χωρίς root και χωρίς 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 method,-gγια να επιλέξετε Gadget version/path,-pγια να επιλέξετε JDWP port. - Λειτουργία ακρόασης: προώθηση Gadget (default 127.0.0.1:27042) αν χρειάζεται:
adb forward tcp:27042 tcp:27042; thenfrida-ps -H 127.0.0.1:27042. - Αυτό αξιοποιεί το JDWP debugging. Ο κίνδυνος είναι η διανομή debuggable builds ή η έκθεση του JDWP.
Αυτόνομος agent + ενσωμάτωση Gadget (Frida 17+; αυτοματοποιημένο με Objection)
Frida 17 αφαίρεσε τα built-in 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 όταν απαιτείται
- Ενσωματώνει έναν static class initializer που καλεί System.loadLibrary(“frida-gadget”) στην launch activity
- Τοποθετεί τα παρακάτω κάτω από
lib/<abi>/: - libfrida-gadget.so
- libfrida-gadget.config.so (σειριοποιημένη διαμόρφωση)
- libfrida-gadget.script.so (το _agent.js σας)
Παράδειγμα injected 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 κατά τη διάρκεια της δυναμικής ανάλυσης
Εφαρμογές που καλούν getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE) αποτρέπουν screenshots, remote displays και ακόμη και τα Android recent-task snapshots. Όταν το Freedom Chat επέβαλε αυτό το flag, ο μόνος τρόπος να τεκμηριώσουμε τα leaks ήταν να παραποιήσουμε το παράθυρο σε runtime. Ένα αξιόπιστο μοτίβο είναι:
- Hook κάθε overload του
Windowπου μπορεί να επανα-εφαρμόσει το flag (setFlags,addFlags,setAttributes) και να μηδενίσει το bit0x00002000(WindowManager.LayoutParams.FLAG_SECURE). - Μετά από κάθε resume της activity, προγραμμάτισε μια κλήση στο UI-thread προς
clearFlags(FLAG_SECURE)ώστε τα Dialogs/Fragments που δημιουργούνται αργότερα να κληρονομήσουν την ξεκλείδωτη κατάσταση. - Εφαρμογές που είναι φτιαγμένες με React Native / Flutter συχνά δημιουργούν nested windows· κάνε hook τους helpers
android.app.Dialog/android.view.Viewή διάσχισε τοgetWindow().peekDecorView()αν συνεχίζεις να βλέπεις μαύρα πλαίσια.
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 δεν υπάρχει flicker, και μπορείς ακόμα να συνδυάσεις το hook με HTTP Toolkit/Burp για να καταγράψεις την κίνηση που αποκάλυψε το `/channel` PIN leak.
## Οδηγοί
### [Tutorial 1](frida-tutorial-1.md)
**Από**: [https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1](https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1)\
**APK**: [https://github.com/t0thkr1s/frida-demo/releases](https://github.com/t0thkr1s/frida-demo/releases)\
**Πηγαίος Κώδικας**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo)
**Ακολούθησε τον [link to read it](frida-tutorial-1.md).**
### [Tutorial 2](frida-tutorial-2.md)
**Από**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (Parts 2, 3 & 4)\
**APKs and Source code**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples)
**Ακολούθησε τον [link to read it.](frida-tutorial-2.md)**
### [Tutorial 3](owaspuncrackable-1.md)
**Από**: [https://joshspicer.com/android-frida-1](https://joshspicer.com/android-frida-1)\
**APK**: [https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk](https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk)
**Ακολούθησε τον [link to read it](owaspuncrackable-1.md).**
**Μπορείς να βρεις περισσότερα Awesome Frida scripts εδώ:** [**https://codeshare.frida.re/**](https://codeshare.frida.re)
## Γρήγορα Παραδείγματα
### Κλήση του Frida από τη γραμμή εντολών
```bash
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 a decryption function. Εκτύπωσε το input, κάλεσε την original function για να decrypt το input και τέλος, εκτύπωσε τα plain data:
Hooking a decryption function (Java) — print inputs/outputs
```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 συναρτήσεις και κλήση τους με το input μας
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
}
Λήψη ενός ήδη δημιουργημένου αντικειμένου μιας κλάσης
Αν θέλετε να εξάγετε κάποια ιδιότητα ενός ήδη δημιουργημένου αντικειμένου, μπορείτε να χρησιμοποιήσετε αυτό.
Σε αυτό το παράδειγμα θα δείτε πώς να πάρετε το αντικείμενο της κλάσης 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
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.


