A test harness for verifying network function hooks on jailed iOS devices.
The project consists of two targets:
| Target | Description |
|---|---|
| Isolator | SwiftUI app with buttons to trigger getifaddrs(), bind(), and connect() |
| IsolatorTweak | Embedded framework that hooks those functions via fishhook (Mach-O symbol rebinding) |
The tweak blocks bind() and connect() to ports 10808 and 10809.
getifaddrs() is filtered to hide any interface whose name contains tun.
| Tool | Install |
|---|---|
| Xcode 15+ | Mac App Store |
| XcodeGen | brew install xcodegen |
| Apple Developer account | Free or paid — needed to sign & deploy to a device |
cd /path/to/isolator
xcodegen generateThis reads project.yml and produces Isolator.xcodeproj.
open Isolator.xcodeproj- Select the Isolator target → Signing & Capabilities.
- Choose your Team and set a unique Bundle Identifier (e.g.
com.yourname.isolator). - Do the same for the IsolatorTweak target (e.g.
com.yourname.isolator.tweak).
- Connect an iOS device (iOS 15+).
- Select the device in Xcode's toolbar.
- ⌘R to build and run.
The IsolatorTweak framework is automatically embedded inside the app bundle. Its __attribute__((constructor)) runs at launch and installs the hooks before any UI code executes.
| Action | Expected result with tweak active |
|---|---|
| Test getifaddrs() | Lists all interfaces except those starting with tun |
| Test bind() on port 10808 | Fails with errno=13 (Permission denied) — EACCES |
| Test connect() on port 10809 | Fails with errno=61 (Connection refused) — ECONNREFUSED |
| Test bind() on port 8080 | Succeeds (or returns a non-hook error like EADDRINUSE) |
| Test connect() on port 8080 | Returns EINPROGRESS (non-blocking) or ECONNREFUSED from the real kernel |
isolator/
├── project.yml # XcodeGen spec
├── .gitignore
├── App/
│ └── Sources/
│ ├── IsolatorApp.swift # @main entry point
│ ├── ContentView.swift # SwiftUI UI
│ └── NetworkTester.swift # BSD socket test functions
├── Tweak/
│ ├── Headers/
│ │ └── IsolatorTweak.h # Public umbrella header
│ └── Sources/
│ ├── Tweak.c # Hook implementations
│ ├── fishhook.h # fishhook API
│ └── fishhook.c # fishhook implementation
└── README.md
- fishhook operates at the Mach-O level by scanning the
__DATAand__DATA_CONSTsegments for lazy and non-lazy symbol pointer tables. - When it finds a pointer matching a target symbol (e.g.
bind), it overwrites the pointer with our hook function and saves the original. - This works in jailed environments because it modifies writable data pages — no code signing violations occur.
- The
__attribute__((constructor))ensures hooks are installed during dyld framework loading, beforemain()runs.
If running on a jailbroken device with ElleKit or CydiaSubstrate available, you can replace the fishhook calls in Tweak.c with:
#include <substrate.h>
__attribute__((constructor))
static void isolator_tweak_init(void) {
MSHookFunction((void *)getifaddrs, (void *)hooked_getifaddrs, (void **)&orig_getifaddrs);
MSHookFunction((void *)bind, (void *)hooked_bind, (void **)&orig_bind);
MSHookFunction((void *)connect, (void *)hooked_connect, (void **)&orig_connect);
}Link against -lsubstrate or the ElleKit framework and remove the fishhook source files.
fishhook is used under the BSD License. See the original repository for details.
If you find this project useful, consider donating:
- TON network:
UQB0t1EOgP2SZOfWK4HMZc_hda0lczGCJzH6-cvuv2ZuFhD7 - TRC20 network:
TYCRxNPqYv342hr4yDzYjm48ruAvL8joj4 - BNB network:
0x0E83d0d058B1A10F079D46fa70760068E305D6eB