
Xnu-QEMU-Arm64: iOS on QEMU - mmastrac
https://github.com/alephsecurity/xnu-qemu-arm64
======
albertzeyer
Probably the blog posts are a better starting point:

\- [https://alephsecurity.com/2019/06/25/xnu-qemu-
arm64-2/](https://alephsecurity.com/2019/06/25/xnu-qemu-arm64-2/)

\- [https://alephsecurity.com/2019/06/17/xnu-qemu-
arm64-1/](https://alephsecurity.com/2019/06/17/xnu-qemu-arm64-1/)

\- Here some more recent screenshots:
[https://twitter.com/JonathanAfek/status/1221719094661197825](https://twitter.com/JonathanAfek/status/1221719094661197825)

------
daeken
This is really awesome for kernel exploitation and such, but for more
practical application testing, I've been working on an alternative solution
for the last two months. Apple's iOS Simulator ships x86_64 binaries for all
the iOS frameworks, so you need to build your application specifically for the
Simulator in order for it to run; obviously a no-go for most cases, e.g. apps
from the store. So I wrote a translation layer that does ARM64 emulation of
the app, while translating calls from ARM->Native libraries and vice versa.

It currently supports most non-Swift apps and a small number of Swift apps;
once I have proper Swift support, pretty much everything should Just Work
(TM). Planning on releasing by end of month (hopefully) for $100/year, aimed
primarily at bug bounty hunters and pentesters, though there's nothing
stopping you from just using it to play an iOS-specific game or somesuch. If
you're curious, you can see Xcode debugging an ARM64 app from the App Store
here -- all of their inspection tools work out of the box!
[https://twitter.com/daeken/status/1242684576738271233](https://twitter.com/daeken/status/1242684576738271233)

~~~
saagarjha
Cool! Is this using something like libffi to translate calls at the
application↔system framework boundary?

~~~
daeken
I wish! Haha. No, it's a custom set of trampoline generators that handle the
transition. I have one for Objective-C (where I can use the internal
reflection tools to get function signatures; fails for variadic functions, so
I wrote my own implementations of those, which live on the ARM side), one for
C (I generated a function signature database for every header file on the
system; otherwise, it shares the trampoline generator with Obj-C), and one for
Swift (this is my WIP right now, where I'm generating a similar function
database. By far the hardest part so far, if only because I'm so much less
familiar with Swift).

There's also a native ARM build of libc++ and libc++abi, so that it doesn't
have to cross the ARM<->Native boundary for C++ stuff, and a bunch of custom
hooks on both sides.

~~~
saagarjha
What are you using for the emulation? QEMU?

~~~
daeken
I was using Unicorn (based on QEMU), but the license isn't conducive to a
closed-source project. So I built my own emulator, which is released under a
more friendly license:
[https://github.com/daeken/libmoonage](https://github.com/daeken/libmoonage)

~~~
saagarjha
I was wondering how the code was that small, and then I saw the LLVM include
;) How are you planning on competing with people running binaries directly on
their iOS devices?

~~~
daeken
For folks with existing setups they're happy with, my tool doesn't provide
much value (aside from more easily working with existing dev tools in Xcode).
But the ability to test real-world apps on any iOS version (mostly) and any
device is pretty damn nice. Definitely a better testing experience than
dealing with jailbreaks, wiping devices all the time, etc.

------
kodablah
I would think there's value in wrapping up all of these steps into an easy-to-
use CLI (that check for deps, download things as needed w/ opt-in custom
paths, etc). Are there legal concerns for making this too easy, or it is just
because this is so young? (I personally toss a `build/main.go` and ask people
to `go run ./build`...but OP may prefer Python or whatever).

~~~
jedieaston
There would be, but since one of the steps is opening the launchd binary and
patching it using a disassembler, I think that any fully automated build
process would have to send binaries along that were patched, which Apple would
clamp down on immediately. Similar to how certain files used to build
Hackintoshes (in the old days) had to be torrented because they were patched.

Maybe someone can automate the patcher and get this going.

~~~
kelnos
It looks like the offset of the instruction that needs to be patched is known
in advance, so there's no need to open it in a GUI editor (for example, to do
some searching for the right place). A python script would suffice -- just
open the file in binary mode, seek to the correct offset, and write out the
new instruction.

~~~
jonyafek
Thanks, these are great suggestions. The project is young and currently we are
prioritizing adding support for UI, SEP and interrupts. We do accept code
contributions so please contact if you would like to add support for something
like this.

------
brabel
I tried QEMU on my Linux laptop to try to use a Windows VM for testing some of
my projects... it was extremely slow, difficult to setup, and after I
restarted my laptop, the VM wouldn't boot anymore... googling the error, I
just found some people asking for lots of magic commands to be run, then I was
supposed to understand the error and run some more commands appropriately to
fix things... I just uninstalled QEMU instead.

I get it that this is the Linux experience :D you fix stuff by knowing your
CLI... but this makes it a huge time-waster for times when all you want is
test your actual product.

Is this experience typical for anyone else? Or am I, after all these years
using Linux, still challenged on the terminal and need to tough the hell up?

~~~
stragies
Installing Windows in a VM on a brand-new laptop in 8 steps:

* Curse your hardware purchasing choice if you have Broadcom or NVidia, because they add (non-dramatic) steps.

* Make sure, everything Virt-related is enabled in the BIOS/UEFI

* Install normal debian default system

* Install virt-manager, libvirt0, qemu-kvm

* Add your desktop user to system groups kvm and libvirt

* Download Windows Iso and Virtio-Drivers iso

* Create new virtual machine, make sure everything possible is set to "VirtIO", mount both ISOs from above as 2 CDROM drives.

* Install Windows, let it search the VirtIO CD for drivers

* Done, total time less than 2 hours on a machine newer than 2015. (No command line required. Just don't use a linux installer from x years ago, but a recent one, e.g. Debian Buster)

~~~
brabel
That's basically what I did... and you're right, took me around 2 hours. The
problem is that when I re-booted the machine, the VM just didn't work anymore
and nothing I did would bring it back to life. I could have spent another 2
hours re-doing everything, if I had infinite amounts of time to play with this
stuff, but I don't.

------
markchristian
I really wish the opposite of this (QEMU on iOS) existed. The closest I have
been able to find is a build of Bochs that doesn't actually work on my iPad.
Someday!

~~~
Operyl
It does! [https://github.com/utmapp/UTM](https://github.com/utmapp/UTM)

~~~
fragmede
Fascinating! Any relation to iSH?

[https://ish.app/](https://ish.app/)

~~~
tbodt
Different projects. iSH has the advantage of not requiring sideloading.

(I wrote iSH)

------
eatbitseveryday
What about macOS itself?

~~~
q3k
macOS on amd64 works well enough on upstream qemu with a few hacks:
[https://github.com/kholia/OSX-KVM](https://github.com/kholia/OSX-KVM)

