Frida-Anleitung
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Installation
Installiere frida tools:
pip install frida-tools
pip install frida
Herunterladen und Installieren auf dem Android-Gerät den frida server (Download the latest release).
Einzeiler, um adb im Root-Modus neu zu starten, sich damit zu verbinden, frida-server hochzuladen, Ausführungsrechte zu vergeben und ihn im Hintergrund auszuführen:
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 &"
Überprüfe ob es funktioniert:
frida-ps -U #List packages and processes
frida-ps -U | grep -i <part_of_the_package_name> #Get all the package name
Frida server vs. Gadget (root vs. no-root)
Zwei gängige Wege, Android-Apps mit Frida zu instrumentieren:
- Frida server (rooted devices): Schiebe und starte einen nativen Daemon, der es dir ermöglicht, dich an jeden Prozess anzuhängen.
- Frida Gadget (no root): Bündle Frida als Shared Library in das APK und lade sie automatisch im Zielprozess.
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)
- Entpacke die APK, füge die gadget .so und die Konfiguration hinzu:
- Lege libfrida-gadget.so in
lib/<abi>/ab (z. B. lib/arm64-v8a/) - Erstelle assets/frida-gadget.config mit deinen Einstellungen zum Laden von Skripten
Beispiel frida-gadget.config
{
"interaction": { "type": "script", "path": "/sdcard/ssl-bypass.js" },
"runtime": { "logFile": "/sdcard/frida-gadget.log" }
}
- Gadget referenzieren/laden, damit es früh initialisiert wird:
- Am einfachsten: Fügen Sie einen kleinen Java-Stub mit System.loadLibrary(“frida-gadget”) in Application.onCreate() hinzu, oder verwenden Sie bereits vorhandenes native lib loading.
- APK neu packen und signieren, dann installieren:
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
- Vom Host an den Gadget-Prozess anhängen:
frida-ps -Uai
frida -U -n com.example.app
Notes
- Gadget wird von einigen Schutzmechanismen erkannt; halte Namen/Pfade unauffällig und lade es bei Bedarf spät/bedingt.
- Bei gehärteten Apps empfiehlt sich rooted testing mit server + late attach, oder die Kombination mit Magisk/Zygisk-Hiding.
JDWP-based Frida injection without root/repackaging (frida-jdwp-loader)
If the APK is debuggable (android:debuggable=“true”), you can attach over JDWP and inject a native library at a Java breakpoint. No root and no APK repackaging.
- Repo: https://github.com/frankheat/frida-jdwp-loader
- Voraussetzungen: ADB, Python 3, USB/Wireless debugging. Die App muss debuggable sein (Emulator mit
ro.debuggable=1, rooted device mitresetprop, oder Manifest neu erstellen).
Quick start
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
Hinweise
- Modi: spawn (break at Application.onCreate) oder attach (break at Activity.onStart). Verwende
-b, um eine spezifische Java-Methode zu setzen,-g, um die Gadget-Version/den Pfad zu wählen,-p, um den JDWP-Port zu wählen. - Listen-Modus: Gadget weiterleiten (Standard 127.0.0.1:27042) falls erforderlich:
adb forward tcp:27042 tcp:27042; dannfrida-ps -H 127.0.0.1:27042. - Dies nutzt JDWP-Debugging. Risiko: das Ausliefern von debuggable Builds oder das Offenlegen von JDWP.
Selbstständiger Agent + Gadget-Einbettung (Frida 17+; automatisiert mit Objection)
Frida 17 hat die eingebauten Java/ObjC-Bridges aus GumJS entfernt. Wenn dein Agent Java hookt, musst du die Java-Bridge in dein Bundle einbinden.
- Erstelle einen Frida-Agenten (TypeScript) und binde die Java-Bridge ein
# 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
Minimaler Java hook (erzwingt Würfelwürfe auf 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);
};
});
Erstelle ein einzelnes Bundle zum Einbetten:
npm run build # produces _agent.js via frida-compile
Kurzer USB-Test (optional):
frida -U -f org.secuso.privacyfriendlydicer -l _agent.js
- Gadget so konfigurieren, dass es dein script automatisch lädt
Objection’s patcher erwartet eine Gadget config; wenn du script mode verwendest, gib den on-disk path innerhalb des APK lib dir an:
{
"interaction": {
"type": "script",
"path": "libfrida-gadget.script.so"
}
}
- APK-Patching mit Objection automatisieren
# 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
Was patchapk macht (auf hoher Ebene):
- Ermittelt die Gerät-ABI (z. B. arm64-v8a) und lädt das passende Gadget herunter
- Fügt optional android.permission.INTERNET hinzu, wenn nötig
- Injiziert einen statischen Klasseninitialisierer, der System.loadLibrary(“frida-gadget”) aufruft, in die Launch-Activity
- Legt Folgendes unter
lib/<abi>/ab: - libfrida-gadget.so
- libfrida-gadget.config.so (serialisierte Konfiguration)
- libfrida-gadget.script.so (dein _agent.js)
Beispiel injiziertes smali (statischer Initialisierer):
.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
- Überprüfe das 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
Erwartete Änderungen:
- AndroidManifest.xml kann
<uses-permission android:name="android.permission.INTERNET"/>enthalten - Neue native libs unter
lib/<abi>/wie oben - Launchable activity smali enthält eine statische
<clinit>, die System.loadLibrary(“frida-gadget”) aufruft
- Split APKs
- Patch die base APK (diejenige, die die MAIN/LAUNCHER activity deklariert)
- Signiere die verbleibenden Splits mit demselben Schlüssel neu:
objection signapk split1.apk split2.apk ...
- Installiere Splits zusammen:
adb install-multiple split1.apk split2.apk ...
- Für die Verteilung kannst du Splits mit APKEditor zu einer einzigen APK zusammenführen und dann align/sign
Anleitungen
Tutorial 1
Von: https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1
APK: https://github.com/t0thkr1s/frida-demo/releases
Quellcode: https://github.com/t0thkr1s/frida-demo
Folge dem Link, um es zu lesen.
Tutorial 2
Von: https://11x256.github.io/Frida-hooking-android-part-2/ (Parts 2, 3 & 4)
APKs and Source code: https://github.com/11x256/frida-android-examples
Folge dem Link, um es zu lesen.
Tutorial 3
Von: https://joshspicer.com/android-frida-1
APK: https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk
Folge dem Link, um es zu lesen.
Weitere großartige Frida-Skripte findest du hier: https://codeshare.frida.re/
Schnelle Beispiele
Frida von der Kommandozeile aufrufen
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.
Grundlegendes Python-Skript
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-Funktionen ohne Parameter
Hook die Funktion a() der Klasse sg.vantagepoint.a.c
Java.perform(function () {
rootcheck1.a.overload().implementation = function() {
send("sg.vantagepoint.a.c.a()Z Root check 1 HIT! su.exists()")
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() und .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 functions mit Parametern und Abrufen des Werts
Hooking a decryption function. Gib die Eingabe aus, rufe die Originalfunktion auf, decrypt die Eingabe und gib schließlich die Klartextdaten aus:
Hooking a decryption function (Java) — Eingaben/Ausgaben ausgeben
```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 und deren Aufruf mit unserem input
Hook eine Funktion, die einen string empfängt, und rufe sie mit einem anderen string auf (aus [hier](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
}
Ein bereits erstelltes Objekt einer Klasse erhalten
Wenn du ein Attribut eines erstellten Objekts extrahieren möchtest, kannst du dies verwenden.
In diesem Beispiel siehst du, wie du das Objekt der Klasse my_activity erhältst und die Funktion .secret() aufrufst, die ein privates Attribut des Objekts ausgibt:
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 () {},
})
Weitere Frida-Tutorials
- https://github.com/DERE-ad2001/Frida-Labs
- Part 1 of Advanced Frida Usage blog series: IOS Encryption Libraries
Referenzen
- 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
Tip
Lernen & üben Sie AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
HackTricks

