Patch and boot custom iOS 27 on an iPhone 11, from a Mac. Built on the usbliter8 exploit.
Two things before you go any further.
It's tethered. The phone only boots from pwn DFU with fw boot, so the Mac has to be there every single time. No Mac, no boot.
And it's iPhone 11 only, n104ap. I don't own another A13 device so that's all i'm willing to claim.
- Normal boot to the home screen, root SSH, apt and Sileo, TrollStore, apps launch
- Cellular, no flags needed. SIM ready, carrier bundle matched, registered on the network
- Calls and SMS over IMS, carried by WiFi Calling, so they need WiFi connected and WiFi Calling on
- USB lockdown pairing, same-boot RemoteXPC reconnect, QuickTime capture, and CoreDevice process listing and screenshots once the DeveloperDiskImage jobs are up
- SEP
- passcode
- Cellular data, and VoLTE with it. The bearer comes up with a real carrier address and the modem acknowledges every instruction, but nothing ever comes back. Narrowed to inside the baseband, with everything above it ruled out: the blocker, and what was eliminated
- Apple services. Push has no token, because minting one needs a real activation record, which needs a SEP-attested key. Measured, not assumed
- xTweak injection. It injects, but it's nowhere near as solid as vphone
- MobileBackup2. Both clients reach the service and negotiate, then the backup fails because the boot has no normal persona state
- 11 Pro and Pro Max. profiles exist but no device to test on
PRs welcome on any of these, especially SEP. The Pro and Pro Max are open too, if you own one and want to take the port on, i'll help where i can. Or if you'd rather help on the hardware side, there's a coffee link and that's what it'd go towards. Either route is fine, and so is neither.
| Firmware | Build | iPhone 11 | 11 Pro | 11 Pro Max |
|---|---|---|---|---|
| iOS 27.0 beta 4 | 24A5390f |
run | - | - |
| iOS 27.0 RC | 24A435 |
run | - | - |
| iOS 27.0 | 24A437 |
run | experimental | experimental |
| iOS 27.0.1 | 24A446 |
run | experimental | experimental |
| iOS 27.2 beta 1 | 24B5084k |
run | - | - |
| iOS 27.2 beta 2 | 24B5089g |
run | - | - |
| iOS 27.2 beta 3 | 24B5099f |
run | - | - |
| iOS 27.2 beta 4 | 24B5110a |
run | - | - |
"Run" means i did an erase restore, booted it normally, then rebooted and it came back up. "Experimental" means unverified. It resolves and you can use it with --experimental, but nobody has confirmed it on that phone. If you own one and are willing to try, share what happens and i'll change the tag.
There's a catch with that table though. fw restore-cfw pulls a fresh APTicket from Apple while the restore is happening, so once Apple drops signing for a build you can't install it anymore. The row stays in the table because i did test it, but that doesn't mean you can still use it today. Check signing first.
Anything not in the table fails before it even gets extracted. The profiles don't carry offsets either, so adding a build isn't a matter of pasting numbers in. The resolvers work them out at runtime.
You need macOS 14 (untested) or newer, Xcode command line tools with Swift 6, and Homebrew.
brew install \
sevenzip blacktop/tap/ipsw gnu-tar coreutils zstd ldid-procursus sshpass autoconf automake libtool pkg-config \
libimobiledevice libimobiledevice-glue libirecovery libusbmuxd libplist libtatsu libzip curlgit clone --recurse-submodules https://github.com/Xplo8E/liter8.git
cd liter8
make setup
make releaseBinary ends up at .build/release/liter8.
Everything lands in one work directory. Set WORK_DIR, or pass --work-dir, or don't and it'll dump into whatever directory you're standing in.
Run the steps in order, every time. Each one eats the output of the one before it. Coming back to a phone days later, restart from fw make-cfw rather than guessing where you left off.
Caution
Step 3 wipes the phone. Erase restore, everything gone, no undo. Read the IPSW path, the device, the build, the board and the work dir twice before you hit enter.
export WORK_DIR="$PWD/.liter8"
.build/release/liter8 fw prepare --file /path/to/firmware.ipswIt gets the build out of BuildManifest.plist and ignores what you named the file. IPSW_FILE does the same job as --file if you'd rather set it once.
.build/release/liter8 fw make-cfwThere's a --serial flag here, and on fw get-rd and fw get-boot. It writes serial=3 into the boot args, which moves the kernel console onto the UART. Useful when you're debugging a boot that dies early. The downside is the phone screen goes quiet, no boot log on the device anymore. It's off by default, and because the literal gets baked in at build time you have to pass it separately for each artifact you build.
Phone in pwn DFU, then:
.build/release/liter8 fw restore-cfwThis checks the CFW over, starts a local TSS proxy, catches the restore ticket on its way through, and shuts the proxy down once idevicerestore exits.
Back to pwn DFU.
.build/release/liter8 fw get-rd
.build/release/liter8 fw boot-rdStep 3 already dropped the ticket at $WORK_DIR/apticket.im4m, so skip --ticket here.
Phone is in SSHRD now. Run these:
.build/release/liter8 fw bootstrap --check
.build/release/liter8 fw bootstrap
.build/release/liter8 fw prepare-rootfs
.build/release/liter8 fw provision --check
.build/release/liter8 fw provision
.build/release/liter8 fw unmount-rootfspwn DFU again.
.build/release/liter8 fw get-boot
.build/release/liter8 fw bootTake the SIM out before going through Setup on a fresh restore. Cellular data doesn't work, so Setup can hang waiting on the network. Put it back once you're on the home screen.
fw get-boot builds TXM with its code-signing policy flags turned on (any signature, unrestricted local signing, relaxed profile trust, CS enforcement disabled, unrestricted task_for_pid) plus the patches C function hooks need. CoreTrust stays enforced. The boot manifest records it as txmPlan: boot-permissive.
Wait until you can SSH into the booted OS, then:
.build/release/liter8 fw finalize --check
.build/release/liter8 fw finalize
.build/release/liter8 fw finalize --checkThe second --check is just so you can see it went through.
Not part of the jailbreak. Skip it unless you want them. The device needs internet for this one, because apt resolves the dependencies on the phone.
.build/release/liter8 fw setup-debuggerInstalls debugserver, re-signed so hardware breakpoints work, plus the TrollStore
Lite helper. Then:
ssh -p 2222 root@localhost \
'nohup /var/jb/usr/bin/debugserver-16 127.0.0.1:1237 --attach=<pid> >/var/root/ds.log 2>&1 &'
ssh -N -L 1237:127.0.0.1:1237 -p 2222 root@127.0.0.1
lldb -o 'platform select remote-ios' -o 'process connect connect://127.0.0.1:1237'
(lldb) breakpoint set -H -n <symbol>-H is not optional: software breakpoints are silently dropped on this platform.
Attaching to a daemon also needs a DeviceSupport tree for your exact build, or lldb
hangs on connect. Both are explained in
docs/design/DEBUGGING_PLATFORM_DAEMONS.md.
Swift does the thinking. Works out which firmware you handed it, parses the binaries, finds the patch sites, checks the bytes are what it expected before writing over them, and deals with IMG4, IM4P, APTickets and DeviceTrees.
Python does the plumbing. Disk images, moving files into place, calling the external tools, walking the device through each stage. There are no offsets anywhere in the Python and i'd like to keep it that way.
Nothing gets written to disk until the whole patch plan has resolved and every pre-image has checked out. Half-applied patches are how you brick things.
Sources/
Liter8CLI/ arg parsing, dispatch
Liter8Core/
Binary/ ARM64, Mach-O, ObjC
Firmware/ IPSW, IMG4/IM4P
Patching/ patch records and guarded writes
Profiles/ build to signature mapping
Payloads/ the bytes each plan writes
Resolvers/
iBoot/ iBSS, iBEC, boot args, display
Kernel/ AMFI, AKS, SEP, sandbox, boot policy
TXM/ restore and normal boot policy
Userland/ restore and post-boot binaries
DeviceTree/
Tests/ same split as above
fixtures/<build>/<board>/
scripts/ host side orchestration
device/ provisioning resources
payloads/ SSHRD payload inputs
tools/ host tools, some built by setup
vendor/ pinned deps
docs/
It's all one Swift target. The folders are there so i can find things, nothing more.
- Architecture and onboarding
- Firmware and device support guide
- iOS 27
24A435resolver and device evidence - iPhone 11 beta 4 device run
- iPhone 11
24A446pairing and watchdog research - Bootstrap and provisioning status
- Normal boot handoff
- Debugging platform daemons
- Baseband and cellular — how each problem was found, and what failed
- How the cellular patches work — what each patch targets, changes and verifies
- Cellular data blocker — self-contained handover: why data still does not flow, what has been ruled out, and what is worth researching next
- Performance backlog
docs/CONTRIBUTING.md. If you're porting a firmware, docs/ADDING_FIRMWARE_SUPPORT.md too.
None of this starts without these people.
wh1te4ever and usbliter8-fun. The beta 2 and beta 3 CFW and ramdisk work is what the beta 4 port was built on top of.
34306, Huy Nguyen, for the fork, the tutorial, and the original patches/ scripts everyone was using.
Procursus for the rootless bootstrap.
khanhduytran0 for the DeviceTree and kernel USB restriction ideas.
tihmstar for img4, img4tool, and the APTicket based IMG4 signing work.
m1stadev and doronz88 for pyimg4 and pymobiledevice3, which the older kernelcache and USB forwarding flows ran on.
Lakr233 for vphone-cli. The Swift CLI shape, the firmware workflow, and the vendored IMG4 integration all came from reading that. Also trollvnc and the USB device control work.
MIT, see LICENSE. Submodules, tools and payloads keep their own licenses.
