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

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)

  1. 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" }
}
  1. 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.
  1. 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
  1. 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 mit resetprop, 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; dann frida-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.

  1. 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
  1. 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"
}
}
  1. 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
  1. Ü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
  1. 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

Referenzen

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