A fork of UTM to enable debugging of macOS guests on macOS 12+ hosts through the Virtualization framework's private GDB stub.
Credits to @_saagarjha for both ideas and code.
Last tested on Apple Silicon running on macOS Monterey 12.3.1 and Xcode 13.3.1.
Either disabling AMFI globally (possibly breaking some apps) or patching the entitlements check with a debugger.
The first approach involves:
-
Updating the
boot-argsvariable:$ sudo nvram boot-args="amfi_get_out_of_my_way=1" -
Adding the entitlement
com.apple.private.virtualizationtoPlatform/macOS/macOS-unsigned.entitlementsbefore building and packaging UTM.
The second approach involves:
-
Disabling System Integrity Protection.
-
Installing an Endpoint Security client that hooks the execution of process
com.apple.Virtualization.VirtualMachineand sendsSIGSTOPto it before allowing it to execute, so to be able to attach to the process with a debugger before the entitlements check. This repository includes an example client in the form of the patch fileMonitoringSystemEventsWithEndpointSecurity.patchto be applied to the sample client provided by Apple (follow the building instructions for AUTH events and sign the app to run locally—no need for a Developer ID certificate and provisioning profile if System Integrity Protection is disabled).
Follow the original documentation to build and package UTM using prebuilt dependencies:
-
Clone submodules:
UTM$ git submodule update --init --recursive -
Download prebuilt dependencies from GitHub Actions and unzip the archive in the project's root directory.
UTM$ ls sysroot-macOS-arm64/ Frameworks/ bin/ host/ include/ lib/ libexec/ qapi/ sbin/ share/ ssl/ var/ -
Build and package UTM:
UTM$ scripts/build_utm.sh -p macos -a arm64 UTM$ scripts/package_mac.sh unsigned ../UTM.xcarchive /tmp/ UTM$ mv /tmp/signed/UTM.app /Applications/
If AMFI has been disabled globally, from the UTM GUI boot the macOS guest and then attach to it from the host with LLDB:
$ lldb
(lldb) gdb-remote 5555If instead the Endpoint Security client has been installed, from the UTM GUI boot the macOS guest (which will immediately stop) and then execute the script resume.sh to automatically patch the entitlements check with LLDB and resume execution; next, attach to the guest from the host with a debugger as explained just above.
Important The VM won't boot if UTM has been built unsigned and Network Mode is set to "Bridged" in the VM settings (it seems to require special entitlements).
Licensed under the Apache License 2.0 in accordance with the original license.