Run 32-bit binaries on 64-bit iOS by passing through syscalls.
Not all apps will work and will mostly run into missing symbols issue. Please open an issue for that.
Note
Some further work in this branch is done by LLM, mainly GPT-5.6 Sol; notable for implementing GDB Stub, Native Threads, more shims, etc. Its commit history is kept for later reference. Last commit before LLM is dbd36e3
While I'd love to work more on it myself more, I can't really do it due to lack of time and I have too many side projects still left in the dust. I still try to review changes. LLM also validates them through test cases made by itself.
Contributions are welcome.
This project is heavily based on unidbg.
There are also missing syscalls that I have yet to provide to pass through. Please see ARM32SyscallHandler.java and DarwinSyscallHandler.java to implement them properly.
Build with Theos, CMake, and Boost 1.57 or newer. See the build guide for SDK requirements and classic linker setup.
git submodule update --init --recursive
gmake -C GuestMakefile generate-shims
gmake -C GuestMakefile
./GuestMakefile/pack-ramdisk.sh
gmakeOn the iOS device, launch an ARM32 binary with the installed app's executable:
/path/to/LiveExec32.app/LiveExec32 /path/to/arm32-binary- Building: prerequisites, downloads, guest RootFS, and macOS testing.
- Configuration and diagnostics: logging, guest environment, and SDK/UIKit compatibility.
- Objective-C proxy bridge: architecture, ownership, and ABI details.
- Compatibility reports: game testing, fixes, and remaining issues.
- LiveExec32 has most of the codebase and references from unidbg, so it also uses Dynarmic as the dynamic translator of ARMv7 code to ARM64.
- The entry point starts from dyld, so it has all of dyld APIs isolated from that of host.
- In
CallSVC, it goes through a long list of guest functions that copy memory regions from input and to output using a page table. Perhaps page bound checks can be added to allow fastpath memory access. - Has a crash reporter and symbolicator for guest code.
- Can emulate bind mount points
- More to be explored...
Hand-written guest framework code lives in GuestFrameworks/<Framework> and
is tracked. GuestFrameworks/.generated/<Framework> is recreated by
GuestMakefile/generate-shims.sh and is intentionally ignored; do not commit
files from it. The generator currently obtains 12 private UIKit fallback
classes from the installed Catalyst runtime, so those particular shims remain
host-dependent until their iOS 10 signatures are captured in the tracked
templates.
Yes. The bundled Dynarmic revision includes the dual-mapping/TXM JIT path required by iOS 26+, while non-iOS hosts remain single-mapped by default.
Yes eta now. During install, LiveExec32 shim is injected to the pending 32-bit app so installd doesn't reject it and makes everything easier to handle.
Idk, need to research into this next
Apache License 2.0