Frida Handleiding
Reading time: 11 minutes
tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: 
HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking: 
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
 - Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
 - Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
 
Installasie
Installeer frida tools:
pip install frida-tools
pip install frida
Laai af en installeer op die Android-toestel die frida server (Download the latest release).
Eenreël-opdrag om adb te herbegin in root-modus, daarmee te koppel, frida-server op te laai, exec permissions te gee en dit in die agtergrond te laat loop:
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 &"
Kontroleer of dit werk:
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)
Twee algemene maniere om Android-apps met Frida te instrumenteer:
- Frida server (rooted devices): Stuur en voer 'n native daemon uit wat jou toelaat om aan enige proses te koppel.
 - Frida Gadget (no root): Bundel Frida as 'n gedeelde biblioteek binne die APK en laai dit outomaties in die teikenproses.
 
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)
- Pak die APK uit, voeg die gadget .so en konfigurasie by:
 
- Plaas libfrida-gadget.so in 
lib/<abi>/(bv. lib/arm64-v8a/) - Skep assets/frida-gadget.config met jou instellings vir die laai van skripte
 
Voorbeeld frida-gadget.config
{
"interaction": { "type": "script", "path": "/sdcard/ssl-bypass.js" },
"runtime": { "logFile": "/sdcard/frida-gadget.log" }
}
- Verwys/laai die gadget sodat dit vroeg geïnitialiseer word:
 
- Eenvoudigste: Voeg 'n klein Java-stub by System.loadLibrary("frida-gadget") in Application.onCreate(), of gebruik reeds bestaande native lib loading.
 
- Herpak en teken die APK, en installeer:
 
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
- Koppel vanaf die gasheer aan die gadget-proses:
 
frida-ps -Uai
frida -U -n com.example.app
Aantekeninge
- Gadget word deur sommige beskermingsmaatreëls opgespoor; hou name/paaie heimlik en laai laat/voorwaardelik indien nodig.
 - By geharde apps, verkies rooted testing met server + late attach, of kombineer dit met Magisk/Zygisk hiding.
 
Self-contained agent + Gadget inbedding (Frida 17+; automated with Objection)
Frida 17 het die ingeboude Java/ObjC bridges uit GumJS verwyder. As jou agent Java hooks, moet jy die Java bridge binne jou bundel insluit.
- Skep 'n Frida agent (TypeScript) en sluit die Java bridge in
 
# 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
Minimale Java hook (dwing dobbelrolle na 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);
};
});
Skep 'n enkele bundel vir inbedding:
npm run build    # produces _agent.js via frida-compile
Vinnige USB-toets (opsioneel):
frida -U -f org.secuso.privacyfriendlydicer -l _agent.js
- Konfigureer Gadget om jou script outomaties te laai Objection se patcher verwag 'n Gadget config; wanneer jy script mode gebruik, spesifiseer die on-disk path binne die APK lib dir:
 
{
"interaction": {
"type": "script",
"path": "libfrida-gadget.script.so"
}
}
- Outomatiseer APK patching met 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
Wat patchapk doen (op hoë vlak):
- Detecteer die toestel se ABI (e.g., arm64-v8a) en haal die ooreenstemmende Gadget
 - Voeg opsioneel android.permission.INTERNET by wanneer dit nodig is
 - Injekteer 'n statiese klass-initialiseerder wat System.loadLibrary("frida-gadget") aanroep in die launch activity
 - Plaas die volgende onder 
lib/<abi>/: - libfrida-gadget.so
 - libfrida-gadget.config.so (geserialiseerde konfigurasie)
 - libfrida-gadget.script.so (jou _agent.js)
 
Voorbeeld ingespuite smali (statiese initialiseerder):
.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
- Verifieer die 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
Verwagte veranderinge:
- AndroidManifest.xml kan insluit 
<uses-permission android:name="android.permission.INTERNET"/> - Nuwe native libs onder lib/
/ soos hierbo  - Launchable activity smali bevat 'n statiese 
<clinit>wat System.loadLibrary("frida-gadget") aanroep 
- Split APKs
 
- Patch die base APK (die een wat MAIN/LAUNCHER activity verklaar)
 - Heronderteken die oorblywende splits met dieselfde sleutel:
 
objection signapk split1.apk split2.apk ...
- Installeer splits saam:
 
adb install-multiple split1.apk split2.apk ...
- Vir verspreiding kan jy splits saamvoeg in 'n enkele APK met APKEditor, en dan align/sign
 
Verdedigingsnotas (waarop om te let tydens hardening)
- Implementeer signature/repackage-kontroles en runtime-integriteit/attestering
 - Detecteer onverwagte System.loadLibrary("frida-gadget") of verdagte native libs by opstart
 - Vermy die verklaring van ongebruikte INTERNET-permissie; verminder gadget-detekteringsoppervlak
 
Handleidings
Handleiding 1
Vanaf: https://medium.com/infosec-adventures/introduction-to-frida-5a3f51595ca1
APK: https://github.com/t0thkr1s/frida-demo/releases
Bronkode: https://github.com/t0thkr1s/frida-demo
Volg die skakel om dit te lees.
Handleiding 2
Vanaf: https://11x256.github.io/Frida-hooking-android-part-2/ (Parts 2, 3 & 4)
APKs en Bronkode: https://github.com/11x256/frida-android-examples
Volg die skakel om dit te lees.
Handleiding 3
Vanaf: https://joshspicer.com/android-frida-1
APK: https://github.com/OWASP/owasp-mstg/blob/master/Crackmes/Android/Level_01/UnCrackable-Level1.apk
Volg die skakel om dit te lees.
Jy kan meer Awesome Frida-skripte hier vind: https://codeshare.frida.re/
Vinnige Voorbeelde
Frida vanaf die opdragreël aanroep
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.
Basiese Python-skrip
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 funksies sonder parameters
Hook die funksie a() van die klas sg.vantagepoint.a.c
Java.perform(function () {
;  rootcheck1.a.overload().implementation = 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() & .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 met parameters en die waarde terugkry
Hooking a decryption function. Druk die invoer, roep die oorspronklike funksie aan om die invoer te decrypt en druk uiteindelik die platte data:
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
}
Hooking functions and calling them with our input
Hook 'n function wat 'n string ontvang en call dit met 'n ander string (van here)
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
}
Verkryding van 'n reeds geskepte objek van 'n klas
As jy 'n attribuut van 'n geskepte objek wil uittrek, kan jy dit gebruik.
In hierdie voorbeeld gaan jy sien hoe om die objek van die klas my_activity te kry en hoe om die funksie .secret() aan te roep wat 'n privaat attribuut van die objek sal afdruk:
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 () {},
})
Ander Frida handleidings
- https://github.com/DERE-ad2001/Frida-Labs
 - Deel 1 van Advanced Frida Usage blogreeks: IOS enkripsiebiblioteke
 
Verwysings
- Bou 'n herhaalbare Android Bug Bounty-lab: Emulator vs Magisk, Burp, Frida en Medusa
 - Frida Gadget dokumentasie
 - Frida vrystellings (bediener-binaire)
 - Objection (SensePost)
 - Modding en verspreiding van mobiele apps met Frida
 
tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking: 
HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking: 
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
 - Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
 - Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
 
HackTricks