| name | ios-frida-pentesting |
| description | 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. |
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
- Jailbroken iOS device (or Corellium VM)
- Frida server running on the device
- Frida tools installed on your machine:
pip install frida frida-tools
Verify Connection
frida-ls-devices
frida-ps -Uia
Core Tasks
1. Enumerate Classes and Methods
Use the bundled scripts to discover app internals:
frida -U <app-bundle> -l scripts/enumerate-classes.js
frida -U <app-bundle> -l scripts/enumerate-methods.js
2. Hook Objective-C Methods
Intercept and modify method calls:
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:
iproxy 2222 22 &
ssh root@localhost -p 2222
debugserver *:5678 --waitfor <BundleName>
iproxy 1234 5678 &
lldb
(lldb) process connect connect://localhost:1234
(lldb) finish
Then patch Swift detection functions:
(lldb) breakpoint set --name '*systemSanityCheck'
(lldb) c
(lldb) finish
(lldb) register write x0 0
(lldb) c
4. Trace Function Calls
Use frida-trace for quick tracing:
frida-trace -U <app> -i "*log*"
frida-trace -U <app> -m "*[* *]"
frida-trace -U <app> -m "*[NE* *authentication*]"
5. Fuzz iOS Applications
Use the bundled fuzzer scripts:
frida -U <app> -l scripts/simple-fuzzer.js
frida -U <app> -l scripts/advanced-fuzzer.js
For production fuzzing with fpicker:
frida-compile scripts/myfuzzer.js -o harness.js
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:
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:
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:
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:
hookMethod("YourClass", "- yourMethod:")
hook-swift.js
Hooks Swift functions using mangled names.
Usage:
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:
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:
findString(str)
findBytes(pattern)
dumpMemory(addr, size)
patchMemory(addr, bytes)
watchMemory(addr, size)
enumerateModules()
findPointers(addr)
getProtection(addr)
changeProtection(addr, size, prot)
Common Patterns
Bypass Authentication
ObjC.classes.AuthManager["- isAuthenticated"].implementation = function() {
console.log("[!] Bypassing authentication!")
return 1
}
Intercept Network Requests
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
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
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
frida-ls-devices
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
frida-trace -U <app> -i "*function_name*"
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
- Start with enumeration - Use
enumerate-classes.js to understand the app structure
- Trace before hooking - Use
frida-trace to find relevant functions
- Test hooks incrementally - Hook one method at a time
- Save crash-inducing inputs - Check
/private/var/mobile/Library/Logs/CrashReporter/
- Use coverage feedback - AFL++ mode in fpicker for better fuzzing
- Monitor for hangs - Add timeouts to detect infinite loops
- Reset state between tests - Restart app after crashes
References
Logs and Crashes
iOS Crash Logs
/private/var/mobile/Library/Logs/CrashReporter/
Settings → Privacy → Analytics & Improvements → Analytics Data
Enable Private Logging
vim /Library/Preferences/Logging/com.apple.system.logging.plist
<key>Enable-Private-Data</key>
<true/>
killall -9 logd
macOS Console
log show --predicate 'process == "<app-name>"' --last 1h
/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