Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bytejmp.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Frida injects a JavaScript engine into a running process. From there, scripts hook native functions, Java/Kotlin methods (Android), and Objective-C/Swift methods (iOS), intercept arguments, modify return values, and trace execution in real time. Works on: Android · iOS · Linux · macOS · Windows

Install

Host (client tools):
pip install frida-tools
Verify:
frida --version
Android device (server):
# Check device architecture
adb shell getprop ro.product.cpu.abi
# e.g. arm64-v8a, armeabi-v7a, x86_64

# Download matching frida-server from:
# https://github.com/frida/frida/releases
# File: frida-server-<version>-android-<arch>.xz

xz -d frida-server-*-android-arm64.xz
adb push frida-server-*-android-arm64 /data/local/tmp/frida-server
adb shell chmod +x /data/local/tmp/frida-server

# Start server (root required)
adb shell su -c "/data/local/tmp/frida-server &"

CLI Tools

CommandDescription
frida-ps -UList processes on USB device
frida-ps -UaList installed apps
frida-ps -UaiList apps with identifiers
frida-trace -U -i "open" <pkg>Trace native function calls
frida -U -f <pkg>Spawn app and attach
frida -U -n <name>Attach to running process by name
frida -U -p <pid>Attach by PID

Attach to App

Spawn (start fresh):
frida -U -f com.example.app --no-pause
Attach to running process:
frida -U -n "App Name"
Load script on attach:
frida -U -f com.example.app -l script.js --no-pause

JavaScript API: Basics

Hook Java Method (Android)

Java.perform(function () {
    var MainActivity = Java.use("com.example.app.MainActivity");

    MainActivity.isUserLoggedIn.implementation = function () {
        console.log("[*] isUserLoggedIn called — returning true");
        return true;
    };
});

Hook with Arguments and Return Value

Java.perform(function () {
    var LoginActivity = Java.use("com.example.app.LoginActivity");

    LoginActivity.checkCredentials.implementation = function (user, pass) {
        console.log("[*] checkCredentials(" + user + ", " + pass + ")");
        var result = this.checkCredentials(user, pass); // call original
        console.log("[*] result: " + result);
        return result;
    };
});

Force Return Value

Java.perform(function () {
    var RootCheck = Java.use("com.example.app.RootCheck");

    RootCheck.isRooted.implementation = function () {
        return false; // always not rooted
    };
});

Enumerate Loaded Classes

Java.perform(function () {
    Java.enumerateLoadedClasses({
        onMatch: function (className) {
            if (className.includes("auth") || className.includes("Auth")) {
                console.log(className);
            }
        },
        onComplete: function () {}
    });
});

SSL Pinning Bypass (Android)

Universal script targeting the most common pinning implementations:
Java.perform(function () {
    // OkHttp3
    try {
        var CertificatePinner = Java.use("okhttp3.CertificatePinner");
        CertificatePinner.check.overload("java.lang.String", "java.util.List").implementation = function () {
            console.log("[*] OkHttp3 CertificatePinner.check bypassed");
        };
    } catch (e) {}

    // TrustManager — accept all certs
    try {
        var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
        TrustManagerImpl.verifyChain.implementation = function () {
            return arguments[0];
        };
    } catch (e) {}

    // SSLContext
    try {
        var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
        var SSLContext = Java.use("javax.net.ssl.SSLContext");
        var TrustManager = Java.registerClass({
            name: "com.frida.TrustManager",
            implements: [X509TrustManager],
            methods: {
                checkClientTrusted: function (chain, authType) {},
                checkServerTrusted: function (chain, authType) {},
                getAcceptedIssuers: function () { return []; }
            }
        });
        SSLContext.init.implementation = function (km, tm, sr) {
            SSLContext.init.call(this, km, [TrustManager.$new()], sr);
        };
    } catch (e) {}
});

Hook Native Functions

// Hook libc open()
Interceptor.attach(Module.findExportByName("libc.so", "open"), {
    onEnter: function (args) {
        console.log("[*] open: " + args[0].readUtf8String());
    },
    onLeave: function (retval) {
        console.log("[*] open returned: " + retval);
    }
});

Read / Write Memory

// Read string from address
var ptr = ptr("0x12345678");
console.log(ptr.readUtf8String());

// Write value
Memory.writeByteArray(ptr, [0x01, 0x02, 0x03]);

Frida Codeshare

Ready-made scripts for common tasks:
frida --codeshare pcipolloni/universal-android-ssl-pinning-bypass-with-frida -U -f com.example.app
Browse scripts: codeshare.frida.re