Frida Handleiding

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

Installatie

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 in root mode te herbegin, daaraan 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): Push en voer ’n native daemon uit wat jou toelaat om by enige proses aan te sluit.
  • Frida Gadget (no root): Pak Frida saam as ’n shared library 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)

  1. Pak die APK uit, voeg die gadget .so en die konfigurasie by:
  • Plaas libfrida-gadget.so in lib/<abi>/ (bv. lib/arm64-v8a/)
  • Skep assets/frida-gadget.config met jou instellings vir script-laai

Voorbeeld frida-gadget.config

{
"interaction": { "type": "script", "path": "/sdcard/ssl-bypass.js" },
"runtime": { "logFile": "/sdcard/frida-gadget.log" }
}
  1. Verwys/laai die gadget sodat dit vroeg geĂŻnisialiseer word:
  • Maklikste: Voeg ’n klein Java-stub by System.loadLibrary(“frida-gadget”) in Application.onCreate(), of gebruik native lib loading wat reeds teenwoordig is.
  1. Herpak en teken die APK, dan 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
  1. Koppel vanaf die gasheer aan by die gadget-proses:
frida-ps -Uai
frida -U -n com.example.app

Notes

  • Gadget word deur sekere verdedigingstelsels opgespoor; hou name/paaie onopvallend en laai laat of voorwaardelik indien nodig.
  • By geharde apps, gee voorkeur aan rooted toetsing met server + late attach, of kombineer met Magisk/Zygisk verberging.

JDWP-gebaseerde Frida injection sonder root/repackaging (frida-jdwp-loader)

Indien die APK debuggable is (android:debuggable=“true”), kan jy oor JDWP aanheg en ’n native library injekteer by ’n Java breakpoint. Geen root en geen APK repackaging nie.

  • 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 with resetprop, or rebuild manifest).

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

Aantekeninge

  • Modusse: spawn (breek by Application.onCreate) of attach (breek by Activity.onStart). Gebruik -b om ’n spesifieke Java-metode te spesifiseer, -g om die Gadget-weergawe/pad te kies, -p om die JDWP-poort te kies.
  • Luister-modus: forward Gadget (standaard 127.0.0.1:27042) indien nodig: adb forward tcp:27042 tcp:27042; dan frida-ps -H 127.0.0.1:27042.
  • Dit benut JDWP debugging. Die risiko is om debuggable builds te versend of JDWP bloot te stel.

Selfstandige agent + Gadget-inkorporering (Frida 17+; geautomatiseer met 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.

  1. 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);
};
});

Bou ’n enkele bundel vir embedding:

npm run build    # produces _agent.js via frida-compile

Vinnige USB-toets (opsioneel):

frida -U -f org.secuso.privacyfriendlydicer -l _agent.js
  1. Konfigureer Gadget om jou script outomaties te laai Objection’s 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"
}
}
  1. 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 toestel-ABI (bv., arm64-v8a) en haal die ooreenstemmende Gadget af
  • Voeg opsioneel android.permission.INTERNET by wanneer nodig
  • Inspuit ’n statiese klas-inisialiseerder 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 inisialiseerder):

.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. 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 mag die volgende insluit <uses-permission android:name="android.permission.INTERNET"/>
  • Nuwe native libs onder lib/<abi>/ soos hierbo
  • Die smali van die launchable-aktiwiteit bevat ’n statiese <clinit> wat System.loadLibrary(“frida-gadget”) aanroep
  1. Split APKs
  • Pas die base APK aan (die een wat die MAIN/LAUNCHER-aktiwiteit 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 distribusie kan jy splits saamvoeg in ’n enkele APK met APKEditor, en dan align/sign

FLAG_SECURE verwyder tydens dinamiese analise

Apps wat getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE) aanroep, voorkom skermskote, remote displays en selfs Android se recent-task snapshots. Toe Freedom Chat hierdie vlag afdwing, was die enigste manier om die leaks te dokumenteer om by die venster tydens runtime te knoei. ’n Betroubare patroon is:

  • Hook elke Window overload wat die vlag weer kan toepas (setFlags, addFlags, setAttributes) en maskeer die bit 0x00002000 (WindowManager.LayoutParams.FLAG_SECURE) uit.
  • Nadat elke activity hervat, skeduleer ’n UI-thread oproep na clearFlags(FLAG_SECURE) sodat Dialogs/Fragments wat later geskep word die ontslote toestand erf.
  • Apps gebou met React Native / Flutter skep dikwels geneste vensters; hook android.app.Dialog/android.view.View helpers of loop deur getWindow().peekDecorView() as jy steeds swart rame sien.
Frida hook wat Window.FLAG_SECURE verwyder ```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>

Voer die skrip uit met `frida -U -f <package> -l disable-flag-secure.js --no-pause`, interakteer met die UI, en skermkiekies/opnames sal weer werk. Omdat alles op die UI thread plaasvind is daar geen flikkering nie, en jy kan steeds die hook met HTTP Toolkit/Burp kombineer om die verkeer wat die `/channel` PIN leak ontbloot het vas te lĂȘ.


## Handleidings

### [Tutorial 1](frida-tutorial-1.md)

**Bron**: [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)\
**Bronkode**: [https://github.com/t0thkr1s/frida-demo](https://github.com/t0thkr1s/frida-demo)

**Volg die [link to read it](frida-tutorial-1.md).**

### [Tutorial 2](frida-tutorial-2.md)

**Bron**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (Parts 2, 3 & 4)\
**APKs en Bronkode**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples)

**Volg die [link to read it.](frida-tutorial-2.md)**

### [Tutorial 3](owaspuncrackable-1.md)

**Bron**: [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)

**Volg die [link to read it](owaspuncrackable-1.md).**

**Jy kan meer Awesome Frida-skripte hier vind:** [**https://codeshare.frida.re/**](https://codeshare.frida.re)

## Vinnige Voorbeelde

### Aanroep van Frida vanaf die opdragreël
```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.

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 functions sonder parameters

Hook die function a() van die class 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() & .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 funksies met parameters en die waarde terugkry

Hooking ’n decryption-funksie. Druk die invoer uit, roep die oorspronklike funksie om die invoer te decrypt en laastens druk die onversleutelde data:

Hooking 'n decryption-funksie (Java) — druk invoere/uitsette ```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 en dit aanroep met ons invoer

Hook 'n funksie wat 'n string ontvang en roep dit aan met 'n ander string (van [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
}

Kry ’n reeds geskepte objek van ’n klas

As jy ’n attribuut van ’n geskepte objek wil onttrek, 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 uitruk:

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-tutorials

Verwysings

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