Skip to content

Frida Cheat Sheet

Overview

Frida is a dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. It allows you to inject JavaScript or your own library into native apps on Windows, macOS, GNU/Linux, iOS, Android, and QNX. Frida provides powerful capabilities for runtime manipulation, API hooking, and dynamic analysis of applications.

⚠️ Warning: Only use Frida on applications you own or have explicit permission to test. Unauthorized use may violate terms of service or local laws.

Installation

Python Package Installation

bash
# Install Frida via pip (recommended)
pip install frida-tools

# Install specific version
pip install frida-tools==12.11.18

# Upgrade to latest version
pip install --upgrade frida-tools

Platform-Specific Installation

Linux

bash
# Ubuntu/Debian
sudo apt update
sudo apt install python3-pip
pip3 install frida-tools

# Arch Linux
sudo pacman -S python-pip
pip install frida-tools

# CentOS/RHEL
sudo yum install python3-pip
pip3 install frida-tools

macOS

bash
# Using Homebrew
brew install python3
pip3 install frida-tools

# Using MacPorts
sudo port install python39 +universal
pip3 install frida-tools

Windows

bash
# Using Python installer
python -m pip install frida-tools

# Using Chocolatey
choco install python3
pip install frida-tools

Mobile Device Setup

Android

bash
# Download Frida server for Android
wget https://github.com/frida/frida/releases/download/16.0.8/frida-server-16.0.8-android-arm64.xz
unxz frida-server-16.0.8-android-arm64.xz

# Push to device and set permissions
adb push frida-server-16.0.8-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server

# Run Frida server on device
adb shell su -c "/data/local/tmp/frida-server &"

iOS

bash
# Install via Cydia (jailbroken devices)
# Add Frida repository: https://build.frida.re

# Or install via SSH
ssh root@<device-ip>
apt update
apt install re.frida.server

Basic Usage

Process Discovery

bash
# List running processes
frida-ps

# List processes on USB device
frida-ps -U

# List processes on remote device
frida-ps -H <host>:<port>

# List applications (Android/iOS)
frida-ps -Uai

# List installed applications
frida-ps -Ua

Basic Hooking

bash
# Attach to running process by name
frida -n "target_app" -l script.js

# Attach to process by PID
frida -p 1234 -l script.js

# Spawn and attach to application
frida -f com.example.app -l script.js --no-pause

# Interactive REPL mode
frida -n "target_app"

Script Execution

bash
# Execute JavaScript file
frida -n "target_app" -l hook_script.js

# Execute inline JavaScript
frida -n "target_app" -e "console.log('Hello from Frida');"

# Execute with USB device
frida -U -f com.example.app -l script.js

# Execute with remote device
frida -H 192.168.1.100:27042 -f com.example.app -l script.js

Command Reference

CommandDescription
frida-psList running processes
frida-ps -UList processes on USB device
frida-ps -UaiList applications on USB device
frida -n <name>Attach to process by name
frida -p <pid>Attach to process by PID
frida -f <app>Spawn and attach to application
frida -l <script>Load JavaScript file
frida -e <code>Execute inline JavaScript
frida-traceTrace function calls
frida-discoverDiscover internal functions
frida-killKill Frida scripts

JavaScript API Basics

Memory Operations

javascript
// Read memory
var addr = ptr("0x12345678");
var value = Memory.readU32(addr);
console.log("Value:", value);

// Write memory
Memory.writeU32(addr, 0xdeadbeef);

// Allocate memory
var buffer = Memory.alloc(1024);
Memory.writeUtf8String(buffer, "Hello World");

// Search memory
var pattern = "48 8b 05 ?? ?? ?? ??";
var matches = Memory.scanSync(ptr("0x400000"), 0x1000, pattern);

Function Hooking

javascript
// Hook function by address
Interceptor.attach(ptr("0x12345678"), {
    onEnter: function(args) {
        console.log("Function called with args:", args[0], args[1]);
        this.arg0 = args[0];
    },
    onLeave: function(retval) {
        console.log("Function returned:", retval);
        retval.replace(ptr("0x1"));
    }
});

// Hook function by name (with Module)
var targetModule = Process.getModuleByName("libc.so");
var mallocAddr = targetModule.getExportByName("malloc");
Interceptor.attach(mallocAddr, {
    onEnter: function(args) {
        console.log("malloc called with size:", args[0].toInt32());
    }
});

Module and Symbol Resolution

javascript
// List loaded modules
Process.enumerateModules().forEach(function(module) {
    console.log(module.name, module.base, module.size);
});

// Get module by name
var module = Process.getModuleByName("libssl.so");
console.log("Base address:", module.base);

// Enumerate exports
module.enumerateExports().forEach(function(exp) {
    console.log(exp.name, exp.address);
});

// Find symbol
var symbol = Module.findExportByName("libc.so", "strcmp");
console.log("strcmp address:", symbol);

Advanced Usage

Android Application Hooking

javascript
// Hook Android Java methods
Java.perform(function() {
    var MainActivity = Java.use("com.example.MainActivity");
    MainActivity.checkLicense.implementation = function() {
        console.log("License check bypassed");
        return true;
    };
    
    // Hook constructor
    MainActivity.$init.implementation = function() {
        console.log("MainActivity constructor called");
        return this.$init();
    };
    
    // Hook with multiple overloads
    var String = Java.use("java.lang.String");
    String.equals.overload("java.lang.Object").implementation = function(obj) {
        var result = this.equals(obj);
        console.log("String.equals called:", this.toString(), "==", obj.toString(), "->", result);
        return result;
    };
});

iOS Application Hooking

javascript
// Hook Objective-C methods
if (ObjC.available) {
    var NSString = ObjC.classes.NSString;
    var method = NSString["- isEqualToString:"];
    
    Interceptor.attach(method.implementation, {
        onEnter: function(args) {
            var self = ObjC.Object(args[0]);
            var other = ObjC.Object(args[2]);
            console.log("NSString isEqualToString:", self.toString(), "==", other.toString());
        }
    });
    
    // Hook class methods
    var UIApplication = ObjC.classes.UIApplication;
    var sharedApplication = UIApplication["+ sharedApplication"];
    
    Interceptor.attach(sharedApplication.implementation, {
        onLeave: function(retval) {
            console.log("UIApplication sharedApplication called");
        }
    });
}

SSL Pinning Bypass

javascript
// Android SSL pinning bypass
Java.perform(function() {
    // Hook TrustManagerImpl
    var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
    TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
        console.log("SSL verification bypassed for: " + host);
        return untrustedChain;
    };
    
    // Hook HttpsURLConnection
    var HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");
    HttpsURLConnection.setDefaultHostnameVerifier.implementation = function(hostnameVerifier) {
        console.log("Default hostname verifier bypassed");
    };
});

Root Detection Bypass

javascript
// Android root detection bypass
Java.perform(function() {
    // Hook common root detection methods
    var RootBeer = Java.use("com.scottyab.rootbeer.RootBeer");
    RootBeer.isRooted.implementation = function() {
        console.log("Root detection bypassed");
        return false;
    };
    
    // Hook file existence checks
    var File = Java.use("java.io.File");
    File.exists.implementation = function() {
        var path = this.getAbsolutePath();
        if (path.indexOf("su") !== -1 || path.indexOf("busybox") !== -1) {
            console.log("Blocked file check for:", path);
            return false;
        }
        return this.exists();
    };
});

Custom Protocol Analysis

javascript
// Hook network functions
var send = Module.findExportByName("libc.so", "send");
var recv = Module.findExportByName("libc.so", "recv");

Interceptor.attach(send, {
    onEnter: function(args) {
        var sockfd = args[0].toInt32();
        var buf = args[1];
        var len = args[2].toInt32();
        
        console.log("Send on socket", sockfd, "length", len);
        console.log(hexdump(buf, { length: len, ansi: true }));
    }
});

Interceptor.attach(recv, {
    onLeave: function(retval) {
        if (retval.toInt32() > 0) {
            console.log("Received", retval.toInt32(), "bytes");
            console.log(hexdump(this.context.r1, { length: retval.toInt32(), ansi: true }));
        }
    }
});

Frida Tools

frida-trace

bash
# Trace all functions in a module
frida-trace -n "target_app" -i "libssl.so!*"

# Trace specific functions
frida-trace -n "target_app" -i "malloc" -i "free"

# Trace with custom handler
frida-trace -n "target_app" -i "strcmp" --runtime=v8

# Trace Java methods (Android)
frida-trace -U -f com.example.app -j '*!*encrypt*'

# Trace Objective-C methods (iOS)
frida-trace -U -f com.example.app -m '*[* *encrypt*]'

frida-discover

bash
# Discover internal functions
frida-discover -n "target_app" -a libssl.so

# Discover with specific patterns
frida-discover -n "target_app" -a libssl.so -s "SSL_*"

# Output to file
frida-discover -n "target_app" -a libssl.so -o discovered_functions.txt

frida-ls-devices

bash
# List available devices
frida-ls-devices

# List with details
frida-ls-devices -l

Automation Scripts

Batch Process Analysis

python
#!/usr/bin/env python3
import frida
import sys

def on_message(message, data):
    if message['type'] == 'send':
        print(f"[*] {message['payload']}")
    else:
        print(message)

# Connect to device
device = frida.get_usb_device()

# List and analyze multiple apps
apps = ['com.example.app1', 'com.example.app2', 'com.example.app3']

for app_id in apps:
    try:
        print(f"[+] Analyzing {app_id}")
        session = device.attach(app_id)
        
        script_code = """
        Java.perform(function() {
            console.log("Analyzing: " + Java.use("android.app.Application").currentApplication().getPackageName());
        });
        """
        
        script = session.create_script(script_code)
        script.on('message', on_message)
        script.load()
        
        input("Press Enter to continue to next app...")
        session.detach()
        
    except Exception as e:
        print(f"[-] Error with {app_id}: {e}")

Automated SSL Pinning Test

python
#!/usr/bin/env python3
import frida
import time

ssl_bypass_script = """
Java.perform(function() {
    console.log("[+] Starting SSL bypass");
    
    // Multiple SSL bypass techniques
    var techniques = [
        function() {
            var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");
            TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
                console.log("[+] SSL verification bypassed for: " + host);
                return untrustedChain;
            };
        },
        function() {
            var X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");
            var TrustManager = Java.registerClass({
                name: "com.frida.TrustManager",
                implements: [X509TrustManager],
                methods: {
                    checkClientTrusted: function(chain, authType) {},
                    checkServerTrusted: function(chain, authType) {},
                    getAcceptedIssuers: function() { return []; }
                }
            });
        }
    ];
    
    techniques.forEach(function(technique, index) {
        try {
            technique();
            console.log("[+] SSL bypass technique " + (index + 1) + " applied");
        } catch (e) {
            console.log("[-] SSL bypass technique " + (index + 1) + " failed: " + e);
        }
    });
});
"""

def test_ssl_bypass(package_name):
    try:
        device = frida.get_usb_device()
        session = device.attach(package_name)
        script = session.create_script(ssl_bypass_script)
        script.load()
        
        print(f"[+] SSL bypass applied to {package_name}")
        time.sleep(5)
        
        session.detach()
        return True
    except Exception as e:
        print(f"[-] Failed to apply SSL bypass to {package_name}: {e}")
        return False

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage: python3 ssl_bypass.py <package_name>")
        sys.exit(1)
    
    test_ssl_bypass(sys.argv[1])

Integration Examples

Burp Suite Integration

python
#!/usr/bin/env python3
import frida
import requests
import json

# Frida script to extract API endpoints
api_extraction_script = """
Java.perform(function() {
    var URL = Java.use("java.net.URL");
    URL.$init.overload("java.lang.String").implementation = function(url) {
        console.log("[API] URL accessed: " + url);
        send({"type": "url", "data": url});
        return this.$init(url);
    };
    
    var HttpURLConnection = Java.use("java.net.HttpURLConnection");
    HttpURLConnection.setRequestMethod.implementation = function(method) {
        console.log("[API] HTTP Method: " + method);
        send({"type": "method", "data": method});
        return this.setRequestMethod(method);
    };
});
"""

def on_message(message, data):
    if message['type'] == 'send':
        payload = message['payload']
        if payload['type'] == 'url':
            # Send to Burp Suite for further analysis
            burp_data = {
                'url': payload['data'],
                'timestamp': time.time()
            }
            # Add to Burp Suite scope or send to Collaborator
            print(f"[+] New API endpoint discovered: {payload['data']}")

# Setup Frida session
device = frida.get_usb_device()
session = device.attach("com.example.app")
script = session.create_script(api_extraction_script)
script.on('message', on_message)
script.load()

input("Press Enter to stop...")

OWASP ZAP Integration

python
#!/usr/bin/env python3
import frida
from zapv2 import ZAPv2

# Initialize ZAP
zap = ZAPv2(proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})

# Frida script to route traffic through ZAP
proxy_script = """
Java.perform(function() {
    var System = Java.use("java.lang.System");
    System.setProperty("http.proxyHost", "127.0.0.1");
    System.setProperty("http.proxyPort", "8080");
    System.setProperty("https.proxyHost", "127.0.0.1");
    System.setProperty("https.proxyPort", "8080");
    
    console.log("[+] Proxy settings configured for ZAP");
});
"""

def setup_zap_integration(package_name):
    device = frida.get_usb_device()
    session = device.attach(package_name)
    script = session.create_script(proxy_script)
    script.load()
    
    print(f"[+] ZAP integration setup for {package_name}")
    print(f"[+] ZAP Spider: {zap.spider.scan('http://target-api.com')}")
    
    return session

# Usage
session = setup_zap_integration("com.example.app")
input("Press Enter to stop...")
session.detach()

Troubleshooting

Common Connection Issues

bash
# Check if Frida server is running on device
adb shell ps | grep frida

# Restart Frida server
adb shell su -c "pkill frida-server"
adb shell su -c "/data/local/tmp/frida-server &"

# Check port forwarding
adb forward --list
adb forward tcp:27042 tcp:27042

# Test connection
frida-ps -U

Permission Issues

bash
# Android: Ensure proper permissions
adb shell su -c "chmod 755 /data/local/tmp/frida-server"
adb shell su -c "chown root:root /data/local/tmp/frida-server"

# iOS: Check Frida installation
ssh root@<device-ip> "dpkg -l | grep frida"

# Reinstall if necessary
ssh root@<device-ip> "apt remove re.frida.server && apt install re.frida.server"

Script Debugging

javascript
// Add comprehensive error handling
try {
    Java.perform(function() {
        // Your code here
    });
} catch (e) {
    console.log("Error in Java.perform:", e);
    console.log("Stack trace:", e.stack);
}

// Use console.log for debugging
console.log("Debug: Variable value is", someVariable);

// Check if classes exist before using
if (Java.available) {
    try {
        var MyClass = Java.use("com.example.MyClass");
        console.log("MyClass found");
    } catch (e) {
        console.log("MyClass not found:", e);
    }
}

Performance Optimization

javascript
// Cache frequently used classes
var cachedClasses = {};
function getClass(className) {
    if (!cachedClasses[className]) {
        cachedClasses[className] = Java.use(className);
    }
    return cachedClasses[className];
}

// Use efficient memory operations
var buffer = Memory.alloc(1024);  // Allocate once
// Reuse buffer instead of allocating repeatedly

// Minimize console output in production
var DEBUG = false;
function debugLog(message) {
    if (DEBUG) {
        console.log(message);
    }
}

Resources


This cheat sheet provides a comprehensive reference for using Frida for dynamic instrumentation and security testing. Always ensure you have proper authorization before using this tool in any environment.