-
Notifications
You must be signed in to change notification settings - Fork 211
Bringing up the emulator
This doc details all the steps to build and run the emulator.
You will need a macOS system for some of the preparation steps.
git clone https://github.com/TrungNguyen1909/qemu-t8030-tools
pip3 install pyasn1
brew install glib libtasn1 meson ninja pixman jtool2 jq coreutils gnutls libgcrypt pkg-config
sudo apt update
sudo apt install -y git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev libtasn1-dev ninja-build build-essential cmake libgnutls28-dev pkg-config
Get jtool2 from the jtool2's official website.
There is a jtool2.ELF64
inside the package.
For Linux, follow the step below to install lzfse.
For macOS, you can install lzfse from Homebrew ONLY if you are running an Intel.
However, there are some problems building when Homebrew uses /opt
prefix (M1 systems).
If you have issues regarding LZFSE, try installing it from sources like below.
git clone https://github.com/lzfse/lzfse
cd lzfse
mkdir build; cd build
cmake ..
make
sudo make install
cd ..
git clone https://github.com/TrungNguyen1909/qemu-t8030
cd qemu-t8030
mkdir build; cd build
../configure --target-list=aarch64-softmmu,x86_64-softmmu --disable-capstone --enable-lzfse --disable-werror
make -j$(nproc)
Continue at here if you want to emulate iPhone 6s SecureROM.
The section following this is for running iOS.
Download and unzip iPhone11,8,iPhone12,1_14.0_18A5351d_Restore.ipsw
curl -LO https://updates.cdn-apple.com/2020SummerSeed/fullrestores/001-35886/5FE9BE2E-17F8-41C8-96BB-B76E2B225888/iPhone11,8,iPhone12,1_14.0_18A5351d_Restore.ipsw
mkdir iphone; cd iphone
unzip ../iPhone11,8,iPhone12,1_14.0_18A5351d_Restore.ipsw
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
These steps are only needed if you want to add your own binaries to the ramdisk.
Note that for all the below steps might need to be run on macOS.
python3 qemu-t8030-tools/bootstrap_scripts/asn1rdskdecode.py 038-44087-125.dmg 038-44087-125.dmg.out
# resize
hdiutil resize -size 512M -imagekey diskimage-class=CRawDiskImage 038-44087-125.dmg.out
# mount
hdiutil attach -imagekey diskimage-class=CRawDiskImage 038-44087-125.dmg.out
# enable ownership
sudo diskutil enableownership /Volumes/AzulSeed18A5351d.arm64eUpdateRamDisk
# Copy system binaries
sudo rsync -av strap/ /Volumes/AzulSeed18A5351d.arm64eUpdateRamDisk
# LaunchDaemons
sudo rm /Volumes/AzulSeed18A5351d.arm64eUpdateRamDisk/System/Library/LaunchDaemons/*
sudo cp qemu-t8030/setup-ios/bash.plist /Volumes/AzulSeed18A5351d.arm64eUpdateRamDisk/System/Library/LaunchDaemons/
# unmount
hdiutil detach /Volumes/AzulSeed18A5351d.arm64eUpdateRamDisk
This step is no longer needed as we now patch AMFI by default.
python3 qemu-t8030-tools/bootstrap_scripts/asn1trustcachedecode.py Firmware/038-44087-125.dmg.trustcache Firmware/038-44087-125.dmg.trustcache.out
python3 qemu-t8030-tools/bootstrap_scripts/dump_trustcache.py Firmware/038-44087-125.dmg.trustcache.out | grep cdhash | cut -d' ' -f2 > tchashes
for filename in $(find strap/ -type f); do jtool2 --sig $filename 2>/dev/null; done | grep CDHash | cut -d' ' -f6 | cut -c 1-40 >> ./tchashes
python3 qemu-t8030-tools/bootstrap_scripts/create_trustcache.py tchashes static_tc
WARNING: This step can take up to 32GB of hard disk.
The problem we are facing here is that macOS cannot mount a qcow2 disk image, so we have no compression.
In order to modify the disk with the macOS host, we need to use a raw disk image.
./qemu-t8030/build/qemu-img create -f raw nvme.1 32G
./qemu-t8030/build/qemu-img create -f raw nvme.2 8M
./qemu-t8030/build/qemu-img create -f raw nvme.3 128K
./qemu-t8030/build/qemu-img create -f raw nvme.4 8K
./qemu-t8030/build/qemu-img create -f raw nvram 8K
./qemu-t8030/build/qemu-img create -f raw nvme.6 4K
./qemu-t8030/build/qemu-img create -f raw nvme.7 1M
Don't forget that -snapshot
can be used to prevent filesystem corruptions on reset.
-smp
can be set up to 6 CPUs.
-m
can go up to 4GB of RAM.
Adding kaslr-off=true
after a comma in the first line will disable KASLR.
This will put the device into Restore mode on the first run and boot to NAND after restore completed
qemu-t8030/build/qemu-system-aarch64 -s -M t8030,trustcache-filename=Firmware/038-44135-124.dmg.trustcache,ticket-filename=root_ticket.der \
-kernel kernelcache.research.iphone12b \
-dtb Firmware/all_flash/DeviceTree.n104ap.im4p \
-append "debug=0x14e kextlog=0xffff serial=3 -v wdt=-1" \
-initrd 038-44135-124.dmg \
-cpu max -smp 4 \
-m 4G -serial mon:stdio \
-drive file=nvme.1,format=raw,if=none,id=drive.1 \
-device nvme-ns,drive=drive.1,bus=nvme-bus.0,nsid=1,nstype=1,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvme.2,format=raw,if=none,id=drive.2 \
-device nvme-ns,drive=drive.2,bus=nvme-bus.0,nsid=2,nstype=2,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvme.3,format=raw,if=none,id=drive.3 \
-device nvme-ns,drive=drive.3,bus=nvme-bus.0,nsid=3,nstype=3,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvme.4,format=raw,if=none,id=drive.4 \
-device nvme-ns,drive=drive.4,bus=nvme-bus.0,nsid=4,nstype=4,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvram,if=none,format=raw,id=nvram \
-device apple-nvram,drive=nvram,bus=nvme-bus.0,nsid=5,nstype=5,id=nvram,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvme.6,format=raw,if=none,id=drive.6 \
-device nvme-ns,drive=drive.6,bus=nvme-bus.0,nsid=6,nstype=6,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvme.7,format=raw,if=none,id=drive.7 \
-device nvme-ns,drive=drive.7,bus=nvme-bus.0,nsid=7,nstype=8,logical_block_size=4096,physical_block_size=4096 \
-monitor telnet:127.0.0.1:1235,server,nowait
Remove rd=md0
boot args from the below commands if you want to boot from NAND instead of ramdisk.
qemu-t8030/build/qemu-system-aarch64 -s -M t8030,trustcache-filename=static_tc,boot-mode=manual,ticket-filename=root_ticket.der \
-kernel kernelcache.research.iphone12b \
-dtb Firmware/all_flash/DeviceTree.n104ap.im4p \
-append "debug=0x14e kextlog=0xffff serial=3 -v rd=md0 wdt=-1" \
-initrd 038-44087-125.dmg.out \
-cpu max -smp 1 \
-m 4G -serial mon:stdio \
-drive file=nvme.1,format=raw,if=none,id=drive.1 \
-device nvme-ns,drive=drive.1,bus=nvme-bus.0,nsid=1,nstype=1,logical_block_size=4096,physical_block_size=4096 \
-drive file=nvram,if=none,format=raw,id=nvram \
-device apple-nvram,drive=nvram,bus=nvme-bus.0,nsid=5,nstype=5,id=nvram,logical_block_size=4096,physical_block_size=4096
You need to get the SecureROM of the S8000 (production) board from securerom.fun
You will also need its DeviceTree from an iPhone 6s IPSW, I tried this version and it works just fine.
The path to the DeviceTree file in the IPSW is Firmware/all_flash/DeviceTree.n71ap.im4p
Create the NOR image if you haven't done so:
./qemu-t8030/build/qemu-img create -f raw s8000.nor 16M
The command to emulate S8000 SecureROM is below:
qemu-t8030/build/qemu-system-aarch64 -s -M s8000,force-dfu=false \
-bios "s8000/SecureROM for s8000si, iBoot-2234.0.0.3.3" \
-dtb DeviceTree.n71ap.im4p \
-cpu max -smp 1 -nographic \
-d guest_errors \
-m 4G -serial mon:stdio \
-drive file=s8000.nor,format=raw,if=none,id=nor \
-device m25p128,drive=nor,bus=spi0.bus \
-monitor telnet:127.0.0.1:1235,server,nowait
You can assert the FORCE_DFU pin (enter DFU mode automatically without reading NOR) by setting force-dfu=true
.
If you have a shell, use the command halt
to shutdown the device gracefully.
Connect to the monitor at localhost:1235
and use the q
command to force quit.
As such, to avoid filesystem corruptions on the NAND, consider using the -snapshot
flag to run without saving changes to your disk.