What is an unsupported Mac? #
A Mac becomes unsupported when Apple’s latest operating system no longer runs on it, without our patches, of course.
Why should I run a patched version of macOS on my unsupported Mac? #
A newer version of macOS means you’ll have better security, and better support for the apps you want to use.
Why should I learn how to patch macOS? #
If you use an automatic patcher tool, you won’t have to do any work by yourself in order to patch macOS, but it’s still cool to know what your tool is doing, isn’t it? If you’d like to develop your own patcher tool, this writeup is a good place to start!
How do I create the installer drive #
The installer disk images were in the InstallESD.dmg up to 10.13, when they were moved to Contents/SharedSupport, set the
asr restore -source <installer_images_path>/BaseSystem.dmg -target <installer_volume_path> -noprompt -noverify -erase
rm <installer_volume_path>/System/Installation/Packages
cp -R <installesd_mount_path>/Packages <installer_volume_path>/System/Installation/
cp <installer_images_path>/BaseSystem.dmg <installer_volume_path>/
cp <installer_images_path>/BaseSystem.chunklist <installer_volume_path>/
cp <installesd_mount_path>/mach_kernel <installer_volume_path>/
You have to patch the OSInstall distribution file to return true on platform compatibility checks. You can do so by running these commands:
pkgutil --expand <installer_volume_path>/tmp/OSInstall.mpkg <installer_volume_path>/tmp/OSInstall
sed -i '' 's/cpuFeatures\[i\] == "VMM"/1 == 1/' <installer_volume_path>/tmp/OSInstall/Distribution
sed -i '' 's/boardID == platformSupportValues\[i\]/1 == 1/' <installer_volume_path>/tmp/OSInstall/Distribution
sed -i '' 's/!boardID || platformSupportValues.length == 0/1 == 0/' <installer_volume_path>/tmp/OSInstall/Distribution
pkgutil --flatten <installer_volume_path>/tmp/OSInstall <installer_volume_path>/tmp/OSInstall.mpkg
OS X 10.8 Mountain Lion #
The 32-bit firmware problem #
Most older Intel Macs have 64-bit CPUs but still use 32-bit firmware, so they can’t load a 64-bit kernel. The MacBook3,1 and MacBook4,1 both have 64-bit firmware but still try to load a 32-bit kernel. The best solution is to use the official file from Yosemite, which seems to work without patches!
If you compile Apple’s boot.efi yourself, you can add support for Macs with 32-bit firmware. Due to the efforts of Piker Alpha, you can download pre-compiled copies from patchers. I used andyvand’s efilipo to combine the compiled 32-bit copy and Yosemite file into one single boot.efi file which supports all unsupported Macs.
OS X 10.11 El Capitan #
The 32-bit firmware problem #
Most older Intel Macs have 64-bit CPUs but still use 32-bit firmware, so they can’t load a 64-bit kernel. El Capitan updated the way kernel cache is handled, and thus needs a recompiled boot.efi file for Macs with 32-bit firmware.
If you compile Apple’s boot.efi yourself, you can add support for Macs with 32-bit firmware. Due to the efforts of Piker Alpha, you can download pre-compiled copies from patchers. I used andyvand’s efilipo to combine the recompiled 32-bit copy and stock file into one single boot.efi file which supports all unsupported Macs.
What new patches do I have to use for this version? #
You have to copy the drivers to a full installation and rebuild the prelinkedkernel from there. El Capitan updated drivers for input devices such as the mouse and keyboard, you have to replace these with older versions from 10.10.5:
- AppleHIDMouse.kext (in /System/Library/Extensions)
- AppleTopCase.kext (in /System/Library/Extensions)
- AppleUSBMultitouch.kext (in /System/Library/Extensions)
- AppleUSBTopCase.kext (in /System/Library/Extensions)
- IOBDStorageFamily.kext (in /System/Library/Extensions)
- IOBluetoothFamily.kext (in /System/Library/Extensions)
- IOBluetoothHIDDriver.kext (in /System/Library/Extensions)
- IOSerialFamily.kext (in /System/Library/Extensions)
- IOUSBFamily.kext (in /System/Library/Extensions)
- IOUSBMassStorageClass.kext (in /System/Library/Extensions)
And this one with a modified version of the stock 10.11.6 copy:
- IOUSBHostFamily.kext (in /System/Library/Extensions)
Specifically, remove the following files from Contents/PlugIns:
- AppleUSBEHCI.kext (in /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns)
- AppleUSBEHCIPCI.kext (in /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns)
- AppleUSBOHCI.kext (in /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns)
- AppleUSBOHCIPCI.kext (in /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns)
- AppleUSBUHCI.kext (in /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns)
- AppleUSBUHCIPCI.kext (in /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns)
What new steps do I have to use for this version? #
El Capitan updated the way kernel cache, which stores cached versions of drivers, is handled. You now have to update it after replacing any drivers. You can do so by running “kextcache -f -u”.
You have to copy the new AppleDiagnostics.dmg after copying the BaseSystem.dmg You can do so with the following commands:
cp <installer_images_path>/AppleDiagnostics.dmg <installer_volume_path>/
cp <installer_images_path>/AppleDiagnostics.chunklist <installer_volume_path>/
macOS 10.12 Sierra #
What new patches do I have to use for this version? #
You have to copy the drivers to a full installation and rebuild the prelinkedkernel from there. You have to replace this one with an older version from 10.12.6:
- macOS Installer.app (in /System/Installation/CDIS)
You have to replace this one with a modified version of the stock 10.12.6 copy:
- Quartz.framework (in /System/Library/Frameworks)
Specifically, replace this file with the current version from /Versions/A/Frameworks:
- QuickLookUI.framework
You have to replace this one with an older version from 10.12 beta 1 installer (this can be obtained from this copy of the macOS 10.12 Sierra beta 1 installer from the Internet Archive):
- OSInstaller.framework (in /System/Library/PrivateFrameworks)
You have to add these custom files from parrotgeek1:
- LegacyUSBInjector.kext (in /System/Library/Extensions)
- SIPManager.kext (in /System/Library/Extensions)
What new steps do I have to use for this version? #
Sierra updated the command for updating the kernel cache, which stores cached versions of drivers. You now have to update it by running “kextcache -i” or “kextcache -u”.
macOS 10.14 Mojave #
What new patches do I have to use for this version? #
You have to copy the drivers to a full installation and rebuild the prelinkedkernel from there. You have to replace these with older versions from 10.13.6:
- IOUSBFamily.kext (in /System/Library/Extensions)
- IOUSBHostFamily.kext (in /System/Library/Extensions)
- SystemMigration.framework (in /System/Library/PrivateFrameworks)
- SystemMigrationUtils.framework (in /System/Library/PrivateFrameworks)
macOS 10.15 Catalina #
The modern installer problem #
Catalina added a new read-only system volume which only works with Apple’s modern installer. After creating the installer drive with openinstallmedia (for versions older than 10.9), you need to mount the BaseSystem.dmg and InstallESD.dmg as shadows, then convert both to read-only, using the following commands:
hdiutil attach -owners on <installer_sharedsupport_path>/BaseSystem.dmg -mountpoint /tmp/Base\ System -nobrowse -noverify -shadow
hdiutil convert -format UDZO <installer_sharedsupport_path>/BaseSystem.dmg -o <installer_volume_path/installer_application>/Contents/SharedSupport/BaseSystem.dmg -shadow
hdiutil attach -owners on <installer_sharedsupport_path>/InstallESD.dmg -mountpoint /tmp/InstallESD -nobrowse -noverify -shadow
hdiutil convert -format UDZO <installer_sharedsupport_path>/InstallESD.dmg -o <installer_volume_path/installer_application>/Contents/SharedSupport/InstallESD.dmg -shadow
dosdude1 patched installer binaries to allow us to modify the installer files without tripping any signature checks. They’re more of a workaround, than a proper solution, and have to be updated for most new Catalina releases. dosdude1 also uses them to run scripts for the APFS software and post-install patches, you may need to replace these with your own scripts/the stock binaries, and sign them with “codesign -f -s”:
- Replace /sbin/apfsbless with /usr/sbin/bless in brtool
- Replace /sbin/runposti with /sbin/shutdown in OSInstaller
- Replace /sbin/apfsinsta with /usr/sbin/nvram in osishelperd
- Replace /sbin/shutdown with /sbin/apfsprep in osishelperd (for installing the APFS software patch)
If you want to understand how these patches were made, I would recommend you reverse engineer and compare the original binaries with the patched binaries using an application like Hopper Disassembler. dosdude1 hasn’t shared the specific assembly code of what was modified, but they can be reproduced by following the diffs obtained by comparing the original ones with the patched ones.
He has however shared this information:
- The patched OSInstallerSetupInternal binary bypasses the OSInstall.mpkg integrity check, APFS firmware check, and BaseSystem integrity check. Having library validation disabled is required in order to get the installer application to launch with this patched binary, which was solved using mologie’s DisableLibraryValidation.kext
- The patched brtool binary bypasses the prelinkedkernel signature check, and booter signature check when the installer app attempts to bless the newly created installer volume.
I found this information by reverse engineering the patched binaries:
- The patched osishelperd binary only replaces
/sbin/shutdown
with/sbin/apfsprep
, or in the case of the patched binary used in his own patcher, replaces/usr/sbin/nvram
with/sbin/apfsinsta
. This patch can be made by using a hex editor, such as the open source Hex Fiend app on macOS.
The APFS firmware problem #
The new read-only system volume only works with APFS. Supported Macs can use it through a firmware update which was bundled with the High Sierra update. Unsupported Macs can’t boot from APFS volumes since they didn’t receive the firmware update.
You can work around this by using an EFI shell script, which loads the stock APFS driver, and boots from the predefined volumes. To do this you’ll have to copy two files into the EFI partition along with the apfs.efi file from /usr/standalone/i386/apfs.efi (this should be dynamically copied by apfsprep before booting to stage 2 of the installer.)
What new patches do I have to use for this version? #
You have to copy the drivers to a full installation and rebuild the prelinkedkernel from there. You have to add this custom file from mologie:
- DisableLibraryValidation.kext (in /System/Library/Extensions)
You have to replace these with modified files from dosdude1:
-
/usr/libexec/brtool -
/System/Library/PrivateFrameworks/OSInstaller.framework/Versions/A/OSInstaller - <installer_volume_path/installer_application>/Contents/Frameworks/OSInstallerSetup.framework/Versions/A/Frameworks/OSInstallerSetupInternal.framework/Versions/A/OSInstallerSetupInternal
- <basesystem_mount_path/installer_application>/Contents/Frameworks/OSInstallerSetup.framework/Versions/A/Frameworks/OSInstallerSetupInternal.framework/Versions/A/OSInstallerSetupInternal
- <installer_volume_path/installer_application>/Contents/Frameworks/OSInstallerSetup.framework/Versions/A/Resources/osishelperd
- <basesystem_mount_path/installer_application>/Contents/Frameworks/OSInstallerSetup.framework/Versions/A/Resources/osishelperd
Catalina Unus #
Catalina Unus is a command line tool for running macOS Catalina on one HFS or APFS volume. It does this by using the BaseSystem.dmg file from Mojave, and making some changes to allow installing using this method and to resemble a Catalina installer. It then copies the template for the Catalina data volume to the system, and makes sure all data in the Recovered Files folder is moved back to the system.
You have to copy these files from a Catalina installer:
- X.tiff (in /Installation/CDIS/macOS\ Installer.apps/Resources)
- kextcache (in /usr/sbin)
You have to replace this one with an older version from 10.12.6:
- macOS Installer.app (in /System/Installation/CDIS)
You have to replace this one with a modified version of the stock 10.12.6 copy:
- Quartz.framework (in /System/Library/Frameworks)
Specifically, replace this file with the current version from /Versions/A/Frameworks:
- QuickLookUI.framework
You have to replace this one with an older version from 10.12 beta 1 installer (this can be obtained from this copy of the macOS 10.12 Sierra beta 1 installer from the Internet Archive):
- OSInstaller.framework (in /System/Library/PrivateFrameworks)
You have to replace these with older versions from 10.13.6:
- SystemMigration.framework (in /System/Library/PrivateFrameworks)
- SystemMigrationUtils.framework (in /System/Library/PrivateFrameworks)
You can do this using the following commands:
cp -R macOS\ Installer.app /tmp/Base\ System/System/Installation/CDIS
cp 10.15/X.tiff /tmp/Base\ System/System/Installation/CDIS/macOS\ Installer.apps/Resources
rm -R /tmp/Base\ System/System/Library/PrivateFrameworks/OSInstaller.framework
cp -R OSInstaller.framework /tmp/Base\ System/System/Library/PrivateFrameworks/
cp -R /tmp/Base\ System/System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/QuickLookUI.framework ~/Downloads
rm -R /tmp/Base\ System/System/Library/Frameworks/Quartz.framework
cp -R Quartz.framework /tmp/Base\ System/System/Library/Frameworks
rm -R /tmp/Base\ System/System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/QuickLookUI.framework
cp -R ~/Downloads/QuickLookUI.framework /tmp/Base\ System/System/Library/Frameworks/Quartz.framework/Versions/A/Frameworks/
rm -R ~/Downloads/QuickLookUI.framework
rm -R /tmp/Base\ System/System/Library/PrivateFrameworks/SystemMigration.framework
rm -R /tmp/Base\ System/System/Library/PrivateFrameworks/SystemMigrationUtils.framework
cp -R SystemMigration.framework /tmp/Base\ System/System/Library/PrivateFrameworks/
cp -R SystemMigrationUtils.framework /tmp/Base\ System/System/Library/PrivateFrameworks/
cp 10.15/kextcache /tmp/Base\ System/usr/sbin
chmod +x /tmp/Base\ System/usr/sbin/kextcache