Tutorial di Frida
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Installazione
Installa frida tools:
pip install frida-tools
pip install frida
Scarica e installa su Android il frida server (Download the latest release).
Comando in una riga per riavviare adb in modalità root, connettersi ad esso, caricare frida-server, assegnare i permessi di esecuzione e avviarlo in background:
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 &"
Verifica se sta funzionando:
frida-ps -U #List packages and processes
frida-ps -U | grep -i <part_of_the_package_name> #Get all the package name
frida-ui (controller Frida basato su browser)
frida-ui fornisce una UI web su http://127.0.0.1:8000 per elencare dispositivi/app e attach o spawn targets con script (non è necessario il CLI).
- Installa (pin
fridaalla versione del device server):
uv tool install frida-ui --with frida==16.7.19
# pipx install frida-ui
# pip install frida-ui
- Esegui:
frida-ui
frida-ui --host 127.0.0.1 --port 8000 --reload
- Caratteristiche: scopre dispositivi USB/locali, aggiunge server remoti (
192.168.1.x:27042) e supporta Attach, Spawn, e Spawn & Run (per effettuare hook prima della logica inizialeonCreate()). - Scripting: editor, drag & drop
.js, importa CodeShare, scarica script e log di sessione. - Server remoti:
./frida-server -l 0.0.0.0:27042 -Dlo espone in rete così frida-ui può connettersi senza ADB.
Frida server vs. Gadget (root vs. no-root)
Due modi comuni per strumentare le app Android con Frida:
- Frida server (rooted devices): Installa e avvia un demone nativo che ti permette di eseguire Attach su qualsiasi processo.
- Frida Gadget (no root): Incorpora Frida come libreria condivisa all’interno dell’APK e la carica automaticamente nel processo target.
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)
- Estrai l’APK, aggiungi il .so del gadget e la config:
- Posiziona libfrida-gadget.so in
lib/<abi>/(e.g., lib/arm64-v8a/) - Crea assets/frida-gadget.config con le impostazioni per il caricamento degli script
Esempio frida-gadget.config
{
"interaction": { "type": "script", "path": "/sdcard/ssl-bypass.js" },
"runtime": { "logFile": "/sdcard/frida-gadget.log" }
}
- Referenzia/carica il gadget in modo che venga inizializzato precocemente:
- Più semplice: Aggiungi un piccolo stub Java con System.loadLibrary(“frida-gadget”) in Application.onCreate(), oppure usa il caricamento nativo delle librerie già presente.
- Ripacchetta e firma l’APK, quindi installalo:
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 dall’host al gadget process:
frida-ps -Uai
frida -U -n com.example.app
Note
- Gadget viene rilevato da alcune protezioni; mantieni nomi/percorsi stealth e caricalo tardi/condizionalmente se necessario.
- Su app protette/hardened, preferisci test su device rooted con server + late attach, oppure combina con Magisk/Zygisk per il nascondimento.
JDWP-based Frida injection without root/repackaging (frida-jdwp-loader)
Se l’APK è debuggable (android:debuggable=“true”), puoi collegarti via JDWP e iniettare una libreria nativa in un breakpoint Java. No root e senza ripacchettare l’APK.
- Repo: https://github.com/frankheat/frida-jdwp-loader
- Requirements: ADB, Python 3, USB/Wireless debugging. App must be debuggable (emulator with
ro.debuggable=1, rooted device withresetprop, or rebuild manifest).
Avvio rapido
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
Note
- Modes: spawn (interrompi in Application.onCreate) or attach (interrompi in Activity.onStart). Use
-bto set a specific Java method,-gto select Gadget version/path,-pto choose JDWP port. - Listen mode: forward Gadget (default 127.0.0.1:27042) if needed:
adb forward tcp:27042 tcp:27042; thenfrida-ps -H 127.0.0.1:27042. - This leverages JDWP debugging. Risk is shipping debuggable builds or exposing JDWP.
Self-contained agent + Gadget embedding (Frida 17+; automated with Objection)
Frida 17 ha rimosso i bridge Java/ObjC integrati da GumJS. Se il tuo agent effettua hook su Java, devi includere il Java bridge all’interno del tuo bundle.
- Create a Frida agent (TypeScript) and include the 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
Hook Java minimale (costringe i lanci dei dadi a 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);
};
});
Crea un singolo bundle per embedding:
npm run build # produces _agent.js via frida-compile
Test USB rapido (opzionale):
frida -U -f org.secuso.privacyfriendlydicer -l _agent.js
- Configura Gadget per caricare automaticamente il tuo script Il patcher di Objection si aspetta una Gadget config; quando usi script mode, specifica il percorso su disco all’interno della APK lib dir:
{
"interaction": {
"type": "script",
"path": "libfrida-gadget.script.so"
}
}
- Automatizzare il patching degli APK con 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
Cosa fa patchapk (a grandi linee):
- Rileva l’ABI del dispositivo (es., arm64-v8a) e recupera il Gadget corrispondente
- Aggiunge opzionalmente android.permission.INTERNET quando necessario
- Inietta un inizializzatore statico di classe che chiama System.loadLibrary(“frida-gadget”) nell’activity di avvio
- Colloca i seguenti file sotto
lib/<abi>/: - libfrida-gadget.so
- libfrida-gadget.config.so (config serializzata)
- libfrida-gadget.script.so (il tuo _agent.js)
Esempio di smali iniettato (inizializzatore statico):
.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
- Verifica il 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
Cambiamenti previsti:
- AndroidManifest.xml potrebbe includere
<uses-permission android:name="android.permission.INTERNET"/> - Nuove librerie native sotto
lib/<abi>/come sopra - Il smali dell’activity avviabile contiene un
<clinit>statico che chiama System.loadLibrary(“frida-gadget”)
- Split APKs
- Patchare l’APK base (quello che dichiara l’attività MAIN/LAUNCHER)
- Rifirmare i split rimanenti con la stessa chiave:
objection signapk split1.apk split2.apk ...
- Installa gli splits insieme:
adb install-multiple split1.apk split2.apk ...
- Per la distribuzione, puoi unire gli split in un unico APK con APKEditor, poi align/sign
Rimuovere FLAG_SECURE durante l’analisi dinamica
Le app che chiamano getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE) impediscono screenshot, display remoti e persino gli snapshot delle attività recenti di Android. Quando Freedom Chat applicava questo flag l’unico modo per documentare i leaks era manomettere la finestra a runtime. Una strategia affidabile è:
- Hook every overload di
Windowche può ri-applicare il flag (setFlags,addFlags,setAttributes) e mascherare il bit0x00002000(WindowManager.LayoutParams.FLAG_SECURE). - Dopo che ogni activity riprende, programma una chiamata sul UI-thread a
clearFlags(FLAG_SECURE)in modo che i Dialogs/Fragments creati successivamente ereditino lo stato sbloccato. - Le app buildate con React Native / Flutter spesso creano window nidificate; hook
android.app.Dialog/android.view.Viewhelpers o percorrigetWindow().peekDecorView()se vedi ancora schermate nere.
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>
Esegui lo script con `frida -U -f <package> -l disable-flag-secure.js --no-pause`, interagisci con la UI, e gli screenshots/recordings funzioneranno di nuovo. Perché tutto avviene sul UI thread non c'è sfarfallio, e puoi comunque combinare il hook con HTTP Toolkit/Burp per catturare il traffico che ha rivelato il leak del PIN `/channel`.
## Tutorial
### [Tutorial 1](frida-tutorial-1.md)
**Fonte**: [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)\
**Codice sorgente**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo)
**Segui il [link per leggerlo](frida-tutorial-1.md).**
### [Tutorial 2](frida-tutorial-2.md)
**Fonte**: [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)
**Segui il [link per leggerlo.](frida-tutorial-2.md)**
### [Tutorial 3](owaspuncrackable-1.md)
**Fonte**: [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)
**Segui il [link per leggerlo](owaspuncrackable-1.md).**
**Puoi trovare altri script Frida qui:** [**https://codeshare.frida.re/**](https://codeshare.frida.re)
## Esempi rapidi
### Chiamare Frida dalla riga di comando
```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.
Script Python di base
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 di funzioni senza parametri
Hook la funzione a() della classe 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() e .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 di 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 di funzioni con parametri e recupero del valore
Hooking di una funzione di decryption. Stampa l’input, chiama la funzione originale per decrypt l’input e infine stampa i dati in chiaro:
Hooking di una funzione di decryption (Java) — stampa input/output
```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 e chiamarle con il nostro input
Effettua l'Hook di una function che riceve una string e chiamala con un'altra string (da [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
}
Ottenere un oggetto già creato di una classe
Se vuoi estrarre un attributo da un oggetto già creato, puoi usare questo.
In questo esempio vedrai come ottenere l’oggetto della classe my_activity e come chiamare la funzione .secret() che stamperà un attributo privato dell’oggetto:
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 () {},
})
Altri tutorial su Frida
- https://github.com/DERE-ad2001/Frida-Labs
- Part 1 of Advanced Frida Usage blog series: IOS Encryption Libraries
Riferimenti
- 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
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord o al gruppo telegram o seguici su Twitter 🐦 @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


