Frida Cheat Sheet for Android

Quick reference for Android app analysis with Frida. See my full guides: Method Hooking and Native Hooking.


Setup & Connection

# Start frida-server on device (run as root)
adb shell "su -c '/data/local/tmp/frida-server &'"

# List running apps
frida-ps -U

# List installed packages
frida-ps -Uai

# Attach to running app
frida -U com.target.app

# Spawn app with script
frida -U -f com.target.app -l script.js --no-pause

# Spawn and wait for input
frida -U -f com.target.app -l script.js

Basic Hooking Template

Java.perform(function() {
    var targetClass = Java.use("com.target.ClassName");
    
    targetClass.methodName.implementation = function(arg1, arg2) {
        console.log("Called with: " + arg1 + ", " + arg2);
        var result = this.methodName(arg1, arg2);
        console.log("Returned: " + result);
        return result;
    };
});

Common Hooks

Hook All Overloads

Java.perform(function() {
    var target = Java.use("com.target.ClassName");
    
    target.methodName.overloads.forEach(function(overload) {
        overload.implementation = function() {
            console.log("methodName called");
            return overload.apply(this, arguments);
        };
    });
});

Hook Constructor

Java.perform(function() {
    var target = Java.use("com.target.ClassName");
    
    target.$init.overload("java.lang.String").implementation = function(arg) {
        console.log("Constructor: " + arg);
        return this.$init(arg);
    };
});

Modify Return Value

Java.perform(function() {
    var target = Java.use("com.target.ClassName");
    
    target.isValid.implementation = function() {
        console.log("isValid() bypassed");
        return true;  // Always return true
    };
});

Access Fields

Java.perform(function() {
    var target = Java.use("com.target.ClassName");
    
    target.methodName.implementation = function() {
        // Read field
        console.log("Field value: " + this.fieldName.value);
        
        // Write field
        this.fieldName.value = "modified";
        
        return this.methodName();
    };
});

Find & Enumerate

Find Loaded Classes

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

Find Class Instances

Java.perform(function() {
    Java.choose("com.target.ClassName", {
        onMatch: function(instance) {
            console.log("Found: " + instance);
            console.log("Field: " + instance.fieldName.value);
        },
        onComplete: function() {}
    });
});

List Methods of a Class

Java.perform(function() {
    var target = Java.use("com.target.ClassName");
    var methods = target.class.getDeclaredMethods();
    
    methods.forEach(function(method) {
        console.log(method.toString());
    });
});

SSL Pinning Bypass

Universal Bypass (Quick)

Java.perform(function() {
    // TrustManager bypass
    var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');
    
    var TrustManagerImpl = Java.registerClass({
        name: 'com.bypass.TrustManager',
        implements: [TrustManager],
        methods: {
            checkClientTrusted: function(chain, authType) {},
            checkServerTrusted: function(chain, authType) {},
            getAcceptedIssuers: function() { return []; }
        }
    });
    
    var ctx = SSLContext.getInstance("TLS");
    ctx.init(null, [TrustManagerImpl.$new()], null);
    SSLContext.setDefault(ctx);
});

OkHttp CertificatePinner

Java.perform(function() {
    var CertificatePinner = Java.use('okhttp3.CertificatePinner');
    
    CertificatePinner.check.overload('java.lang.String', 'java.util.List')
        .implementation = function(hostname, peerCertificates) {
        console.log("Bypassing pin for: " + hostname);
        return;
    };
});

String & Crypto Hooks

Log All String Operations

Java.perform(function() {
    var StringBuilder = Java.use("java.lang.StringBuilder");
    
    StringBuilder.toString.implementation = function() {
        var result = this.toString();
        if (result.length > 0 && result.length < 500) {
            console.log("StringBuilder: " + result);
        }
        return result;
    };
});

Hook Encryption

Java.perform(function() {
    var Cipher = Java.use("javax.crypto.Cipher");
    
    Cipher.doFinal.overload("[B").implementation = function(input) {
        console.log("Cipher.doFinal input: " + byteArrayToHex(input));
        var result = this.doFinal(input);
        console.log("Cipher.doFinal output: " + byteArrayToHex(result));
        return result;
    };
});

function byteArrayToHex(byteArray) {
    var hex = [];
    for (var i = 0; i < byteArray.length; i++) {
        hex.push(('0' + (byteArray[i] & 0xFF).toString(16)).slice(-2));
    }
    return hex.join('');
}

Hook SharedPreferences

Java.perform(function() {
    var SharedPrefs = Java.use("android.app.SharedPreferencesImpl");
    
    SharedPrefs.getString.implementation = function(key, defValue) {
        var result = this.getString(key, defValue);
        console.log("SharedPrefs.getString(" + key + ") = " + result);
        return result;
    };
});

Native Hooking (Interceptor)

Hook Native Function by Export

Interceptor.attach(Module.findExportByName("libnative.so", "native_function"), {
    onEnter: function(args) {
        console.log("Arg 0: " + args[0]);
        console.log("Arg 1: " + Memory.readUtf8String(args[1]));
    },
    onLeave: function(retval) {
        console.log("Return: " + retval);
    }
});

Hook Native Function by Address

var baseAddr = Module.findBaseAddress("libnative.so");
var targetAddr = baseAddr.add(0x1234);  // offset from IDA/Ghidra

Interceptor.attach(targetAddr, {
    onEnter: function(args) {
        console.log("Hit target function");
    }
});

Replace Native Function

Interceptor.replace(Module.findExportByName("libnative.so", "checkLicense"), 
    new NativeCallback(function() {
        console.log("License check bypassed");
        return 1;  // Return success
    }, 'int', [])
);

Read Native Memory

var addr = Module.findExportByName("libnative.so", "secret_key");
console.log("Key: " + Memory.readUtf8String(addr));
console.log("Hex: " + hexdump(addr, { length: 32 }));

Useful One-Liners

// Get current activity
Java.use("android.app.ActivityThread").currentApplication().getApplicationContext()

// Get package name
Java.use("android.app.ActivityThread").currentApplication().getPackageName()

// Stack trace
Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())

// Load DEX at runtime
Java.openClassFile("/data/local/tmp/payload.dex").load()

Objection Quick Commands

# Start with objection
objection -g com.target.app explore

# Common commands
android hooking list classes
android hooking list class_methods com.target.ClassName
android hooking watch class com.target.ClassName
android sslpinning disable
android root disable