# IOS Frida Pentesting

> iOS mobile security testing with Frida instrumentation. Use this skill whenever the user needs to perform iOS app pentesting, hook Objective-C/Swift methods, bypass jailbreak detection, fuzz iOS applications, inspect memory, or analyze iOS binaries. Trigger for any iOS security assessment, reverse engineering, or dynamic analysis tasks involving Frida.

- Skill: `abelrguezr/ios-frida-pentesting` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/ios-frida-pentesting`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/ios-frida-pentesting/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/ios-frida-pentesting

---


# iOS Frida Pentesting Skill

A comprehensive skill for iOS mobile security testing using Frida instrumentation framework.

## When to Use This Skill

Use this skill when the user:
- Needs to perform iOS application security testing
- Wants to hook or trace Objective-C/Swift methods
- Needs to bypass jailbreak or Frida detection
- Wants to fuzz iOS applications
- Needs to inspect or manipulate iOS app memory
- Is doing iOS reverse engineering or dynamic analysis
- Needs to enumerate iOS app classes, methods, or exports

## Quick Start

### Prerequisites

1. **Jailbroken iOS device** (or Corellium VM)
2. **Frida server** running on the device
3. **Frida tools** installed on your machine:
   ```bash
   pip install frida frida-tools
   ```

### Verify Connection

```bash
frida-ls-devices    # List connected devices
frida-ps -Uia       # List running processes
```

## Core Tasks

### 1. Enumerate Classes and Methods

Use the bundled scripts to discover app internals:

```bash
# List all Objective-C classes
frida -U <app-bundle> -l scripts/enumerate-classes.js

# List methods for a specific class
frida -U <app-bundle> -l scripts/enumerate-methods.js
```

### 2. Hook Objective-C Methods

Intercept and modify method calls:

```bash
# Hook authentication methods
frida -U <app-bundle> -l scripts/hook-objc.js
```

The script hooks common patterns:
- Login/Authentication methods
- Data storage (NSUserDefaults)
- Crypto operations
- Network requests

### 3. Bypass Jailbreak Detection

Use LLDB + Frida combination for production builds:

```bash
# Forward SSH to device
iproxy 2222 22 &
ssh root@localhost -p 2222

# On device, spawn debugger
debugserver *:5678 --waitfor <BundleName>

# On macOS, attach LLDB
iproxy 1234 5678 &
lldb
(lldb) process connect connect://localhost:1234
(lldb) finish  # Run until constructors complete
```

Then patch Swift detection functions:

```bash
(lldb) breakpoint set --name '*systemSanityCheck'
(lldb) c
(lldb) finish
(lldb) register write x0 0  # Force return false
(lldb) c
```

### 4. Trace Function Calls

Use `frida-trace` for quick tracing:

```bash
# Trace functions containing "log"
frida-trace -U <app> -i "*log*"

# Trace all Objective-C methods
frida-trace -U <app> -m "*[* *]"

# Trace specific class methods
frida-trace -U <app> -m "*[NE* *authentication*]"
```

### 5. Fuzz iOS Applications

Use the bundled fuzzer scripts:

```bash
# Simple standalone fuzzer
frida -U <app> -l scripts/simple-fuzzer.js

# Advanced fuzzer with crash monitoring
frida -U <app> -l scripts/advanced-fuzzer.js
```

For production fuzzing with fpicker:

```bash
# Compile fuzzer script
frida-compile scripts/myfuzzer.js -o harness.js

# Run with fpicker
fpicker -v --fuzzer-mode active -e attach -p <app> -D usb \
  -o ./out/ -i ./in/ -f harness.js \
  --standalone-mutator cmd --mutator-command "radamsa"
```

### 6. Memory Inspection

Scan and manipulate process memory:

```bash
frida -U <app> -l scripts/memory-scan.js
```

Available functions (use in Frida console):
- `findString(str)` - Search for strings in memory
- `findBytes(pattern)` - Search for byte patterns
- `dumpMemory(address, size)` - Dump memory region
- `patchMemory(address, [bytes])` - Write to memory
- `watchMemory(address, size)` - Monitor memory changes
- `enumerateModules()` - List loaded modules
- `findPointers(address)` - Find pointers to address

## Script Reference

### enumerate-classes.js
Lists all Objective-C classes in the target app.

**Usage:**
```bash
frida -U <app> -l scripts/enumerate-classes.js
```

**Configuration:**
- Set `filterClass` variable to filter by substring
- Leave empty to list all classes

### enumerate-methods.js
Lists all methods for a specific Objective-C class.

**Usage:**
```bash
frida -U <app> -l scripts/enumerate-methods.js
```

**Configuration:**
- Set `specificClass` to target class name
- Set `filterMethod` to filter methods by substring

### hook-objc.js
Hooks common Objective-C methods for security testing.

**Pre-configured hooks:**
- `LoginViewController.authenticate:`
- `AuthManager.validatePassword:`
- `NSUserDefaults` methods
- `NSString.dataUsingEncoding:`
- `NSURLSession.dataTaskWithRequest:completionHandler:`

**To add custom hooks:**
```javascript
hookMethod("YourClass", "- yourMethod:")
```

### hook-swift.js
Hooks Swift functions using mangled names.

**Usage:**
```bash
frida -U <app> -l scripts/hook-swift.js
```

**Configuration:**
- Set `MODULE_NAME` to the dylib name
- Set `FUNCTION_NAME` to the mangled Swift symbol
- Use `frida-trace` to discover mangled names

### simple-fuzzer.js
Standalone fuzzer without fpicker dependency.

**Usage:**
```bash
frida -U <app> -l scripts/simple-fuzzer.js
```

**Configuration:**
- `TARGET_MODULE` - App binary name
- `TARGET_FUNCTION` - Function to fuzz
- `ITERATIONS` - Number of fuzz iterations
- `MAX_PAYLOAD_SIZE` - Maximum payload size

**Mutation strategies:**
- Buffer overflow (long strings)
- Format string bugs
- Null bytes and boundary characters
- SQL injection patterns
- XSS payloads
- Path traversal
- Invalid Unicode
- Random binary data

### advanced-fuzzer.js
Fuzzer with crash monitoring and signal handlers.

**Features:**
- Exception handler for crashes
- Hooks dangerous functions (abort, malloc, free)
- Timeout detection for hangs
- Detailed crash reporting with backtraces

### memory-scan.js
Memory inspection and manipulation toolkit.

**Exported functions:**
```javascript
findString(str)           // Search for string
findBytes(pattern)        // Search for byte pattern
dumpMemory(addr, size)    // Dump memory region
patchMemory(addr, bytes)  // Write to memory
watchMemory(addr, size)   // Monitor changes
enumerateModules()        // List modules
findPointers(addr)        // Find pointers to address
getProtection(addr)       // Get memory protection
changeProtection(addr, size, prot)  // Change protection
```

## Common Patterns

### Bypass Authentication

```javascript
// Hook authentication method
ObjC.classes.AuthManager["- isAuthenticated"].implementation = function() {
  console.log("[!] Bypassing authentication!")
  return 1  // Always return true
}
```

### Intercept Network Requests

```javascript
ObjC.classes.NSURLSession["- dataTaskWithRequest:completionHandler:"].implementation = function(request, handler) {
  console.log("[+] Network request:", request.URL)
  console.log("[+] Headers:", request.allHTTPHeaderFields)
  return this.$super["- dataTaskWithRequest:completionHandler:"](request, handler)
}
```

### Capture Sensitive Data

```javascript
// Hook string encoding to capture data before encryption
ObjC.classes.NSString["- dataUsingEncoding:"].implementation = function(encoding) {
  var str = this.toString()
  console.log("[+] String being encoded:", str)
  return this.$super["- dataUsingEncoding:"](encoding)
}
```

### Read Keychain Data

```javascript
// Hook SecItemCopyMatching
Interceptor.attach(Module.findExportByName(null, "SecItemCopyMatching"), {
  onEnter: function(args) {
    console.log("[+] Keychain query:", JSON.stringify(args[0].readUtf8String()))
  },
  onLeave: function(retval) {
    console.log("[+] Keychain result:", retval)
  }
})
```

## Troubleshooting

### Device Not Detected

```bash
# Check USB connection
frida-ls-devices

# For Corellium, ensure frida-gadget is in correct location
cp frida-gadget-*.dylib /Users/[user]/.cache/frida/gadget-ios.dylib
```

### App Crashes on Attach

- Try LLDB-assisted approach for anti-instrumentation apps
- Use `--no-pause` flag: `frida -U -f <app> --no-pause`
- Check for jailbreak detection and bypass it first

### Swift Functions Not Found

```bash
# Discover mangled names
frida-trace -U <app> -i "*function_name*"

# Use the mangled name in your script
Module.findExportByName("<module>", "$s16App11ContentViewV13functionNameySS_tF")
```

### Memory Scan Returns Nothing

- Ensure you're scanning readable ranges: `Process.enumerateRanges('r--')`
- Try different memory permissions: `r-x`, `rw-`, `rwx`
- Check if the data is in a different module

## Best Practices

1. **Start with enumeration** - Use `enumerate-classes.js` to understand the app structure
2. **Trace before hooking** - Use `frida-trace` to find relevant functions
3. **Test hooks incrementally** - Hook one method at a time
4. **Save crash-inducing inputs** - Check `/private/var/mobile/Library/Logs/CrashReporter/`
5. **Use coverage feedback** - AFL++ mode in fpicker for better fuzzing
6. **Monitor for hangs** - Add timeouts to detect infinite loops
7. **Reset state between tests** - Restart app after crashes

## References

- [Frida Documentation](https://frida.re/docs/)
- [Reversing Training](https://reversing.training/)
- [iOS Security Guide](https://www.apple.com/business/docs/iOS_Security_Guide.pdf)
- [Fpicker Fuzzer](https://github.com/ttdennis/fpicker)

## Logs and Crashes

### iOS Crash Logs

```bash
# On device
/private/var/mobile/Library/Logs/CrashReporter/

# Via Settings
Settings → Privacy → Analytics & Improvements → Analytics Data
```

### Enable Private Logging

```bash
# Edit logging config
vim /Library/Preferences/Logging/com.apple.system.logging.plist

# Add:
<key>Enable-Private-Data</key>
<true/>

# Restart logging
killall -9 logd
```

### macOS Console

```bash
# View logs
log show --predicate 'process == "<app-name>"' --last 1h

# Check crash reports
/Library/Logs/DiagnosticReports/
~/Library/Logs/DiagnosticReports/
```

## Notes

- iOS only stores 25 crashes per app - clean old reports regularly
- Frida hooks may prevent iOS crash report generation
- For production testing, use LLDB + Frida combination
- Swift ABI: small strings (≤15 bytes) inline in x0, large strings heap-backed at x1+32

