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

Installasie

Installeer frida tools:

pip install frida-tools
pip install frida

Laai af en installeer op die Android die frida server (Download the latest release).
Eenreël-opdrag om adb in root-modus te herbegin, daaraan te koppel, frida-server op te laai, uitvoerregte 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-ui (blaaier-gebaseerde Frida beheerder)

frida-ui voorsien ’n web UI op http://127.0.0.1:8000 om toestelle/apps te lys en targets aan te koppel of te spawn met scripts (geen CLI nodig nie).

  • Installeer (pin frida aan die device server-weergawe):
uv tool install frida-ui --with frida==16.7.19
# pipx install frida-ui
# pip install frida-ui
  • Voer uit:
frida-ui
frida-ui --host 127.0.0.1 --port 8000 --reload
  • Kenmerke: ontdek USB/lokale toestelle, voeg afgeleë bedieners (192.168.1.x:27042) by, en ondersteun Attach, Spawn, en Spawn & Run (to hook before early onCreate() logic).
  • Skriptering: editor, sleep & los .js, importeer CodeShare, aflaai skripte en sessielogs.
  • Afgeleë bedieners: ./frida-server -l 0.0.0.0:27042 -D maak dit op die netwerk sigbaar sodat frida-ui kan connect sonder ADB.

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 aan enige proses te attach.
  • Frida Gadget (no root): Bundel Frida as ’n shared library binne die APK en auto-load dit binne 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 config 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" }
}
  1. Verwys/laai die gadget sodat dit vroeg geïnitialiseer word:
  • Maklikste: Voeg ’n klein Java-stub by System.loadLibrary(“frida-gadget”) in Application.onCreate(), of gebruik die reeds bestaande native lib loading.
  1. Herpak en teken die APK, dan installeer dit:
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. Attach vanaf die host na die gadget process:
frida-ps -Uai
frida -U -n com.example.app

Aantekeninge

  • Gadget word deur sommige beskermingsmaatreëls opgespoor; hou name/paaie onopvallend en laai laat of voorwaardelik indien nodig.
  • By geharde apps, verkies rooted-toetsing met server + late attach, of kombineer met Magisk/Zygisk verberging.

JDWP-gebaseerde Frida-inspuiting sonder root/herverpakking (frida-jdwp-loader)

As die APK debuggable is (android:debuggable=“true”), kan jy oor JDWP aanheg en ’n native library by ’n Java-breekpunt inject. Geen root en geen APK-herverpakking nodig.

  • Repo: https://github.com/frankheat/frida-jdwp-loader
  • Vereistes: ADB, Python 3, USB/Wireless debugging. Die app moet debuggable wees (emulator met ro.debuggable=1, rooted device met resetprop, of herbou die manifest).

Vinnige begin:

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 (break at Application.onCreate) of attach (break at Activity.onStart). Gebruik -b om ’n spesifieke Java method te stel, -g om Gadget version/path te kies, -p om JDWP port te kies.
  • Luister-modus: forward Gadget (default 127.0.0.1:27042) indien nodig: adb forward tcp:27042 tcp:27042; daarna frida-ps -H 127.0.0.1:27042.
  • Dit benut JDWP debugging. Die risiko is die verskaf van debuggable builds of die blootstelling van JDWP.

Self-contained agent + Gadget embedding (Frida 17+; geoutomatiseer met Objection)

Frida 17 het die ingeboude Java/ObjC bridges uit GumJS verwyder. As jou agent Java hooks, moet jy die Java bridge in jou bundle 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 ingebedding:

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 pad op die skyf 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 ’n hoë vlak):

  • Detecteer die toestel se ABI (bv., arm64-v8a) en haal die paslike Gadget
  • Voeg opsioneel android.permission.INTERNET by wanneer nodig
  • Inspuit ’n statiese klas-initialiseerder wat System.loadLibrary(“frida-gadget”) in die launch activity aanroep
  • Plaas die volgende onder lib/<abi>/:
  • libfrida-gadget.so
  • libfrida-gadget.config.so (serialized config)
  • libfrida-gadget.script.so (your _agent.js)

Voorbeeld van 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
  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 <uses-permission android:name="android.permission.INTERNET"/> insluit
  • Nuwe native libs onder lib/<abi>/ soos hierbo
  • Launchable activity smali bevat ’n statiese <clinit> wat System.loadLibrary(“frida-gadget”) aanroep
  1. Split APKs
  • Patch die base APK (die een wat die MAIN/LAUNCHER activity verklaar)
  • Re-sign 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

Verwydering van FLAG_SECURE tydens dinamiese analise

Aansoeke wat getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE) aanroep verhinder skermkiekies, remote displays en selfs Android se recent-task snapshots. Toe Freedom Chat hierdie vlag afgedwing het, was die enigste manier om die leaks te dokumenteer om die venster tydens runtime te manipuleer. ’n Betroubare patroon is:

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

Run the script with `frida -U -f <package> -l disable-flag-secure.js --no-pause`, interact with the UI, and skermskote/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 vas te vang wat die `/channel` PIN leak onthul het.

## Dynamiese DEX dumping / unpacking with clsdumper (Frida)

`clsdumper` is 'n Frida-based dinamiese **DEX/class dumper** wat geharde apps oorleef deur 'n anti-Frida pre-stage met native en Java discovery strategies te kombineer (werk selfs as `Java.perform()` sterf). Vereistes: Python 3.10+, toestel met root-toegang en `frida-server` aan die gang, USB of `--host` TCP-verbinding.

**Install & quick use**
```bash
pip install clsdumper
# Attach to a running app
clsdumper com.example.app
# Spawn first (hooks before early loaders)
clsdumper com.example.app --spawn
# Select strategies
clsdumper com.example.app --strategies fart_dump,oat_extract

CLI-opsies (mees nuttig)

  • target: pakketnaam of PID.
  • --spawn: spawn in plaas van attach.
  • --host <ip>: verbind met ’n afgeleë frida-server.
  • --strategies <comma>: beperk/kies extractors; verstek is almal behalwe mmap_hook (prestasie-intensief).
  • --no-scan / --deep-scan: skakel die diepe geheue-skandering af of maak dit stadiger (voeg CDEX-skandering by).
  • --extract-classes: nabehandel dumps na .smali via androguard.
  • --no-anti-frida: sla die pre-hook bypass-fase oor.
  • --list / --list-apps: som lopende prosesse of geïnstalleerde pakkette op.

Anti-instrumentation bypass (phase 0)

  • Hooks sigaction/signal om registrasie van crash/anti-debug handlers te blokkeer.
  • Dien ’n gefiltreerde /proc/self/maps via memfd_create om Frida-gebiede te verberg.
  • Monitor pthread_create om watchdog-threads wat Frida jag, te vang/neutraliseer.

DEX discovery (phases 1–2) — verskeie aanvullende strategieë met per-treffer metadata + deduplisering (agent-side djb2, host-side SHA-256):

  • Native (no Java bridge needed): art_walk (loop ART Runtime→ClassLinker→DexFile), open_common_hook (hook DexFile::OpenCommon), memory_scan (DEX magic in leesbare maps), oat_extract (ontleed gemapte .vdex/.oat), fart_dump (hook DefineClass + loop deur class_table_), dexfile_constructor (hook OatDexFile constructors), mmap_hook (kyk na mmap/mmap64, standaard afgeskakel vir prestasie).
  • Java (when available): cookie (lees mCookie van ClassLoaders), classloader_hook (monitor loadClass, DexClassLoader, InMemoryDexClassLoader).

Uitsetindeling

dump_<target>/
dex/classes_001.dex ...
classes/                 # only when --extract-classes
metadata.json            # strategy per hit + hashes

Wenk: beskermde apps laai dikwels kode vanaf verskeie bronne (in-memory payload, vdex/oat, custom loaders). Om met die standaard multi-strategy set plus --spawn te werk maksimeer dekking; skakel --deep-scan slegs aan wanneer nodig om prestasie-impakte te vermy.

Handleidings

Handleiding 1

Bron: 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

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

Volg die skakel om dit te lees.

Handleiding 3

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

Hook die function a() van die class 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() en .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 verkryging van die waarde

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

Hooking a decryption function (Java) — druk insette/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 van funksies en hulle met ons invoer aanroep

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
}

Verkry ’n reeds aangemaakte objek van ’n klas

As jy ’n attribuut van ’n aangemaakte objek wil uithaal, 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 private 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

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