Skip to content

Instantly share code, notes, and snippets.

@WitherOrNot
Last active June 15, 2025 19:04
Show Gist options
  • Save WitherOrNot/71d2d91009ea070d8bfc5ce3e35936bb to your computer and use it in GitHub Desktop.
Save WitherOrNot/71d2d91009ea070d8bfc5ce3e35936bb to your computer and use it in GitHub Desktop.
Emulate iOS on Linux

Emulate iOS on Linux

This is a set of notes, meant to serve as a companion to the primary instruction set.

Companion VM

Use Arch Boxes basic images for the VM.

For installing dependencies, you can use AUR to install usbmuxd-git and libirecovery-git, then manually build patched idevicerestore.

Filesystem Patching

Build linux-apfs-rw. On WSL, you will need to build the WSL Linux kernel to make it compile.

Load it like so:

modprobe crc32c
insmod /path/to/apfs.ko

Mount the system disk like so:

# /mnt/ios can be replaced with any mountpoint you want
mkdir -p /mnt/ios
losetup -fP --show -b 4096 /path/to/nvme.1
# /dev/loop0 should be replaced with the shown device name
mount -t apfs -o readwrite /dev/loop0p1 /mnt/ios

In PatchDYLD.sh, replace /Volumes/System with your mountpoint. Then download this launchd.plist and copy like so:

cp /path/to/launchd.plist /mnt/ios/System/Library/xpc/launchd.plist

iOS Setup

On the Quick Setup screen, tap the Accessibility icon.

Enable the following settings:

Motion > Reduce Motion
Motion > Prefer Cross-Fade Transitions
Display & Text Size > Reduce Transparency
Touch > AssistiveTouch > AssistiveTouch

Make sure to have no passcode, no Face ID. At Express Settings screen, select "Customize Settings" and say no to everything.

Networking

On the companion VM, run:

systemctl edit usbmuxd

Add the following:

[Service]
Environment=USBMUXD_DEFAULT_DEVICE_MODE=3

and run systemctl restart usbmuxd.

Then, setup dnsmasq:

pacman -S dnsmasq
systemctl stop systemd-resolved
systemctl disable systemd-resolved
systemctl mask systemd-resolved
systemctl disable dnsmasq
rm /etc/resolv.conf
echo "nameserver 8.8.8.8" > /etc/resolv.conf

Boot up the iOS VM, then check interfaces with ip a. You should see an extra interface with status DOWN.

Now we run the following commands:

# Replace eth1 with your iPhone interface
ip addr add dev eth1 192.168.1.1/24
ip link set dev eth1 up
dnsmasq -d -i eth1 -K -F 192.168.1.2,192.168.1.3

Then just wait a bit. You should eventually see in the logs that the VM requested and got an IP.

Now, run these commands to set up networking:

COMPAN_VM_INTERFACE=eth0
IOS_VM_INTERFACE=eth1

iptables -t nat -A POSTROUTING -o $COMPAN_VM_INTERFACE -j MASQUERADE
iptables -A FORWARD -i $IOS_VM_INTERFACE -o $COMPAN_VM_INTERFACE -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i $COMPAN_VM_INTERFACE -o $IOS_VM_INTERFACE -j ACCEPT
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward=1" > /etc/sysctl.d/70-forwarding.conf

Bootstrapping APT

First mount nvme.1 like in Filesystem Patching.

Next, grab and install a base bootstrap from checkra1n:

export STRAP_URL=$(curl https://assets.checkra.in/loader/config.json | jq -r ".core_bootstrap_tar")
curl -LO $STRAP_URL
mkdir strap
tar xf strap.tar.lzma -C strap
sudo rsync -av strap/ /mnt/ios

Now, run these commands on your host/WSL:

wget https://apt.procurs.us/bootstraps/iphoneos-arm64/1700/bootstrap-ssh-iphoneos-arm.tar.zst
zstd -d bootstrap-ssh-iphoneos-arm.tar.zst
python3 -m http.server

Boot into iOS and hit enter in the serial console a few times, you should see a bash prompt. There, run:

mount -urw /
mkdir /strap && cd /strap
wget http://10.0.2.2:8000/bootstrap-ssh-iphoneos-arm.tar
tar --preserve-permissions -xvf bootstrap-ssh-iphoneos-arm.tar -C /
export NO_PASSWORD_PROMPT=1
/prep_bootstrap.sh
apt-get install -f
apt-get update -o Acquire::AllowInsecureRepositories=true
apt-get dist-upgrade -y --allow-downgrades --allow-unauthenticated

And that's it. You can install TrollStore now as well:

wget https://github.com/opa334/TrollStore/releases/download/2.1/com.opa334.trollstorehelper_2.1_iphoneos-arm.deb
dpkg -i com.opa334.trollstorehelper_2.1_iphoneos-arm.deb
uicache -v

You can also start up the ssh server:

ssh-keygen -A
/usr/sbin/sshd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment