diff --git a/OpenCore-Patcher.command b/OpenCore-Patcher.command
index bf3822aea..efb5493da 100755
--- a/OpenCore-Patcher.command
+++ b/OpenCore-Patcher.command
@@ -119,11 +119,11 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
menu = Utilities.TUIMenu(title, "Please select an option: ", auto_number=True, top_level=True)
options = [
[f"Assume Metal GPU Always:\t\tCurrently {self.constants.imac_vendor}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).change_metal],
- [f"Assume Upgraded Wifi Always:\tCurrently {self.constants.wifi_build}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).change_wifi],
+ #[f"Assume Upgraded Wifi Always:\tCurrently {self.constants.wifi_build}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).change_wifi],
[f"Set SMBIOS Mode:\t\t\tCurrently {self.constants.serial_settings}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).change_serial],
[f"DRM Preferences:\t\t\tCurrently {self.constants.drm_support}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).drm_setting],
[f"Set Generic Bootstrap:\t\tCurrently {self.constants.boot_efi}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).bootstrap_setting],
- [f"Assume Legacy GPU:\t\t\tCurrently {self.constants.assume_legacy}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).force_accel_setting],
+ #[f"Assume Legacy GPU:\t\t\tCurrently {self.constants.assume_legacy}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).force_accel_setting],
[f"Disable CPU Friend:\t\t\tCurrently {self.constants.disallow_cpufriend}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).disable_cpufriend],
[f"Override SMBIOS Spoof:\t\tCurrently {self.constants.override_smbios}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).set_smbios],
[f"Set Custom name {self.constants.custom_cpu_model_value}", CliMenu.MenuOptions(self.constants.custom_model or self.current_model, self.constants).custom_cpu],
@@ -150,12 +150,12 @@ system_profiler SPHardwareDataType | grep 'Model Identifier'
def PatchVolume(self):
Utilities.cls()
Utilities.header(["Patching System Volume"])
- print("""Patches Root volume to fix misc issues such as:
+ big_sur = """Patches Root volume to fix misc issues such as:
- Graphics Acceleration for non-Metal GPUs
- Nvidia: Tesla - Fermi (8000-500 series)
- Intel: Ironlake - Sandy Bridge
- - AMD: TeraScale 1 (2000-4000 series)
+ - AMD: TeraScale 1 and 2 (2000-6000 series)
- Audio support for iMac7,1 and iMac8,1
WARNING: Root Volume Patching is still in active development, please
@@ -168,7 +168,30 @@ Supported Options:
1. Patch System Volume
2. Unpatch System Volume (Experimental)
B. Exit
- """)
+ """
+ monterey = """Patches Root volume to fix misc issues such as:
+
+- Basic Framebuffer and brightness Control (No acceleration)
+ - Nvidia: Tesla - Fermi (8000-500 series)
+ - Intel: Ironlake - Sandy Bridge
+ - AMD: TeraScale 1 and 2 (2000-6000 series)
+- Audio support for iMac7,1 and iMac8,1
+
+WARNING: Root Volume Patching is still in active development, please
+have all important user data backed up. Note when the system volume
+is patched, you can no longer have Delta updates or have FileVault
+enabled.
+
+Supported Options:
+
+1. Patch System Volume
+2. Unpatch System Volume (Experimental)
+B. Exit
+ """
+ if self.constants.detected_os > self.constants.big_sur:
+ print(monterey)
+ else:
+ print(big_sur)
change_menu = input("Patch System Volume?: ")
if change_menu == "1":
SysPatch.PatchSysVolume(self.constants.custom_model or self.current_model, self.constants).start_patch()
@@ -184,7 +207,6 @@ B. Exit
title = [
f"OpenCore Legacy Patcher v{self.constants.patcher_version}",
f"Selected Model: {self.constants.custom_model or self.current_model}",
- f"Target OS: macOS {self.constants.os_support}",
]
if (self.constants.custom_model or self.current_model) not in ModelArray.SupportedSMBIOS and self.constants.allow_oc_everywhere is False:
diff --git a/Resources/ModelArray.py b/Resources/ModelArray.py
index d5a37f1a1..098d3c5ca 100644
--- a/Resources/ModelArray.py
+++ b/Resources/ModelArray.py
@@ -1244,6 +1244,9 @@ AddIntelGen3Accel = [
"AppleIntelHD4000GraphicsGLDriver.bundle",
"AppleIntelHD4000GraphicsMTLDriver.bundle",
"AppleIntelHD4000GraphicsVADriver.bundle",
+ "IOSurface.kext",
+ "IOGPUFamily.kext",
+ "IOAcceleratorFamily2.kext",
]
AddGeneralAccel = [
diff --git a/Resources/SysPatch.py b/Resources/SysPatch.py
index fc60652fd..5ed6a05ce 100644
--- a/Resources/SysPatch.py
+++ b/Resources/SysPatch.py
@@ -20,17 +20,29 @@ class PatchSysVolume:
def __init__(self, model, versions):
self.model = model
self.constants: Constants.Constants = versions
- self.sip_patch_status = True
self.root_mount_path = None
- self.sip_status = None
+ self.sip_enabled = True
+ self.sbm_enabled = True
+ self.amfi_enabled = True
+ self.fv_enabled = True
+ self.nvidia_legacy = False
+ self.amd_ts1 = False
+ self.amd_ts2 = False
+ self.iron_gpu = False
+ self.sandy_gpu = False
+ self.ivy_gpu = False
+ self.nvidia_legacy = False
+ self.brightness_legacy = False
+ self.legacy_audio = False
+ self.added_kexts = False
+ self.amfi_must_disable = False
+ self.no_patch = True
- # TODO: Put this in a better place
- if self.constants.recovery_status is True:
- if not Path("/Volumes/mnt1").exists:
- self.elevated(["mkdir", "/Volumes/mnt1"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- self.mount_location = "/Volumes/mnt1"
- else:
+ if self.constants.detected_os > self.constants.catalina:
+ # Big Sur and newer use APFS snapshots
self.mount_location = "/System/Volumes/Update/mnt1"
+ else:
+ self.mount_location = "/"
self.mount_extensions = f"{self.mount_location}/System/Library/Extensions"
self.mount_frameworks = f"{self.mount_location}/System/Library/Frameworks"
self.mount_lauchd = f"{self.mount_location}/System/Library/LaunchDaemons"
@@ -42,130 +54,9 @@ class PatchSysVolume:
else:
return subprocess.run(["sudo"] + [args[0][0]] + args[0][1:], **kwargs)
- def csr_decode(self, print_status):
- sip_int = int.from_bytes(self.sip_status, byteorder="little")
- i = 0
- for current_sip_bit in self.constants.csr_values:
- if sip_int & (1 << i):
- temp = True
- self.constants.csr_values[current_sip_bit] = True
- else:
- temp = False
- if print_status is True:
- print(f"- {current_sip_bit}\t {temp}")
- i = i + 1
-
- sip_needs_change = all(
- self.constants.csr_values[i]
- for i in [
- "CSR_ALLOW_UNTRUSTED_KEXTS",
- "CSR_ALLOW_UNRESTRICTED_FS",
- "CSR_ALLOW_UNRESTRICTED_DTRACE",
- "CSR_ALLOW_UNRESTRICTED_NVRAM",
- "CSR_ALLOW_DEVICE_CONFIGURATION",
- "CSR_ALLOW_UNAPPROVED_KEXTS",
- "CSR_ALLOW_EXECUTABLE_POLICY_OVERRIDE",
- "CSR_ALLOW_UNAUTHENTICATED_ROOT",
- ]
- )
- if sip_needs_change is True:
- self.sip_patch_status = False
- else:
- self.sip_patch_status = True
-
- def recovery_root_mount(self):
- def human_fmt(num):
- for unit in ["B", "KB", "MB", "GB", "TB", "PB"]:
- if abs(num) < 1000.0:
- return "%3.1f %s" % (num, unit)
- num /= 1000.0
- return "%.1f %s" % (num, "EB")
-
- print("- Starting Root Volume Picker")
- # Planned logic:
- # Load "diskutil list -plist"
- # Find all APFSVolumes entries where VolumeName is not named Update, VM, Recovery or Preboot
- # Omit any VolumeName entries containing "- Data"
- # Parse remianing options for macOS 11.x with /Volumes/$disk/System/Library/CoreServices/SystemVersion.plist
- # List remaining drives as user options
- all_disks = {}
- disks = plistlib.loads(subprocess.run("diskutil list -plist".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
- for disk in disks["AllDisksAndPartitions"]:
- disk_info = plistlib.loads(subprocess.run(f"diskutil info -plist {disk['DeviceIdentifier']}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
- try:
- all_disks[disk["DeviceIdentifier"]] = {"identifier": disk_info["DeviceNode"], "name": disk_info["MediaName"], "size": disk_info["TotalSize"], "partitions": {}}
- for partition in disk["Partitions"] + disk.get("APFSVolumes", []):
- partition_info = plistlib.loads(subprocess.run(f"diskutil info -plist {partition['DeviceIdentifier']}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
- all_disks[disk["DeviceIdentifier"]]["partitions"][partition["DeviceIdentifier"]] = {
- "fs": partition_info.get("FilesystemType", partition_info["Content"]),
- "type": partition_info["Content"],
- "name": partition_info.get("VolumeName", ""),
- "size": partition_info["TotalSize"],
- "sealed": partition_info.get("Sealed", "No"),
- }
- except KeyError:
- # Avoid crashing with CDs installed
- continue
- menu = Utilities.TUIMenu(
- ["Select Disk"],
- "Please select the disk you would like to patch: ",
- in_between=["Missing disks? Ensure they have a macOS Big Sur install present."],
- return_number_instead_of_direct_call=True,
- loop=True,
- )
- for disk in all_disks:
- if not any(all_disks[disk]["partitions"][partition]["fs"] == "apfs" for partition in all_disks[disk]["partitions"]):
- continue
- menu.add_menu_option(f"{disk}: {all_disks[disk]['name']} ({human_fmt(all_disks[disk]['size'])})", key=disk[4:])
-
- response = menu.start()
-
- if response == -1:
- return
-
- disk_identifier = "disk" + response
- selected_disk = all_disks[disk_identifier]
-
- menu = Utilities.TUIMenu(
- ["Select Partition"],
- "Please select the partition you would like to install OpenCore to: ",
- return_number_instead_of_direct_call=True,
- loop=True,
- in_between=["Missing disks? Ensure they have a macOS Big Sur install present.", "", "* denotes likely candidate."],
- )
- # TODO: check if Big Sur, when macOS 12 comes out
- for partition in selected_disk["partitions"]:
- if selected_disk["partitions"][partition]["fs"] != "apfs":
- continue
- text = f"{partition}: {selected_disk['partitions'][partition]['name']} ({human_fmt(selected_disk['partitions'][partition]['size'])})"
- if selected_disk["partitions"][partition]["sealed"] != "No":
- text += " *"
- menu.add_menu_option(text, key=partition[len(disk_identifier) + 1 :])
-
- response = menu.start()
-
- if response == -1:
- return
- else:
- return f"{disk_identifier}s{response}"
-
def find_mount_root_vol(self, patch):
- if self.constants.recovery_status is True:
- print("- Running RecoveryOS logic")
- self.root_mount_path = self.recovery_root_mount()
- if not self.root_mount_path:
- return
- print(f"- Root Mount Path: {self.root_mount_path}")
- if not Path(self.constants.payload_mnt1_path).exists():
- print("- Creating mnt1 folder")
- Path(self.constants.payload_mnt1_path).mkdir()
- else:
- root_partition_info = plistlib.loads(subprocess.run("diskutil info -plist /".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
- self.root_mount_path = root_partition_info["DeviceIdentifier"]
-
+ self.root_mount_path = Utilities.get_disk_path()
if self.root_mount_path.startswith("disk"):
- if self.constants.recovery_status is False:
- self.root_mount_path = self.root_mount_path[:-2] if self.root_mount_path.count("s") > 1 else self.root_mount_path
print(f"- Found Root Volume at: {self.root_mount_path}")
if Path(self.mount_extensions).exists():
print("- Root Volume is already mounted")
@@ -176,16 +67,8 @@ class PatchSysVolume:
self.unpatch_root_vol()
return True
else:
- if self.constants.recovery_status is True:
- print("- Mounting drive as writable in Recovery")
-
- umount_drive = plistlib.loads(subprocess.run(f"diskutil info -plist {self.root_mount_path}".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
- umount_drive = umount_drive["VolumeName"]
- self.elevated(["umount", f'/Volumes/{umount_drive}'], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- self.elevated(["mount", "-t", "apfs", "-rw", f"/dev/{self.root_mount_path}", self.mount_location], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- else:
- print("- Mounting drive as writable in OS")
- self.elevated(["mount", "-o", "nobrowse", "-t", "apfs", f"/dev/{self.root_mount_path}", self.mount_location], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ print("- Mounting drive as writable in OS")
+ self.elevated(["mount", "-o", "nobrowse", "-t", "apfs", f"/dev/{self.root_mount_path}", self.mount_location], stdout=subprocess.PIPE).stdout.decode().strip().encode()
if Path(self.mount_extensions).exists():
print("- Successfully mounted the Root Volume")
if patch is True:
@@ -197,10 +80,46 @@ class PatchSysVolume:
else:
print("- Failed to mount the Root Volume")
print("- Recommend rebooting the machine and trying to patch again")
- input("- Press [ENTER] to exit")
+ input("- Press [ENTER] to exit: ")
else:
print("- Could not find root volume")
- input("- Press [ENTER] to exit")
+ input("- Press [ENTER] to exit: ")
+
+ def unpatch_root_vol(self):
+ print("- Reverting to last signed APFS snapshot")
+ self.elevated(["bless", "--mount", self.mount_location, "--bootefi", "--last-sealed-snapshot"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+
+ def rebuild_snapshot(self):
+ if self.constants.gui_mode is False:
+ input("Press [ENTER] to continue with cache rebuild: ")
+ print("- Rebuilding Kernel Cache (This may take some time)")
+ result = self.elevated(["kmutil", "install", "--volume-root", self.mount_location, "--update-all"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+ if result.returncode != 0:
+ self.success_status = False
+ print("- Unable to build new kernel cache")
+ print("\nPlease report this to Github")
+ print("Reason for Patch Failure:")
+ print(result.stdout.decode())
+ print("")
+ print("\nPlease reboot the machine to avoid potential issues rerunning the patcher")
+ input("Press [ENTER] to continue")
+ else:
+ self.success_status = True
+ print("- Successfully built new kernel cache")
+ if self.constants.gui_mode is False:
+ input("Press [ENTER] to continue with snapshotting")
+ print("- Creating new APFS snapshot")
+ self.elevated(["bless", "--folder", f"{self.mount_location}/System/Library/CoreServices", "--bootefi", "--create-snapshot"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ self.unmount_drive()
+ print("- Patching complete")
+ print("\nPlease reboot the machine for patches to take effect")
+ input("Press [ENTER] to continue")
+
+
+ def unmount_drive(self):
+ print("- Unmounting Root Volume (Don't worry if this fails)")
+ self.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
def delete_old_binaries(self, vendor_patch):
for delete_current_kext in vendor_patch:
@@ -223,201 +142,154 @@ class PatchSysVolume:
self.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
def add_brightness_patch(self):
- print("- Merging legacy Brightness Control Patches")
self.delete_old_binaries(ModelArray.DeleteBrightness)
self.add_new_binaries(ModelArray.AddBrightness, self.constants.legacy_brightness)
self.elevated(["ditto", self.constants.payload_apple_private_frameworks_path_brightness, self.mount_private_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
self.elevated(["chmod", "-Rf", "755", f"{self.mount_private_frameworks}/DisplayServices.framework"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
self.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_private_frameworks}/DisplayServices.framework"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- def gpu_accel_patches_11(self):
- igpu_vendor, igpu_device, igpu_acpi = DeviceProbe.pci_probe().gpu_probe("IGPU")
- dgpu_vendor, dgpu_device, dgpu_acpi = DeviceProbe.pci_probe().gpu_probe("GFX0")
- if dgpu_vendor:
- print(f"- Found GFX0: {dgpu_vendor}:{dgpu_device}")
- if dgpu_vendor == self.constants.pci_nvidia:
- if dgpu_device in PCIIDArray.nvidia_ids().tesla_ids or dgpu_device in PCIIDArray.nvidia_ids().fermi_ids:
- print("- Merging legacy Nvidia Tesla and Fermi Kexts and Bundles")
- self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
- self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
- self.add_new_binaries(ModelArray.AddNvidiaAccel11, self.constants.legacy_nvidia_path)
- self.added_kexts = True
- # TODO: Enable below code if macOS 12 drops support
- # elif dgpu_device in PCIIDArray.nvidia_ids().kepler_ids and self.constants.detected_os > self.constants.big_sur:
- # print("- Merging legacy Nvidia Kepler Kexts and Bundles")
- # self.add_new_binaries(ModelArray.AddNvidiaKeplerAccel11, self.constants.legacy_nvidia_kepler_path)
- elif dgpu_vendor == self.constants.pci_amd_ati:
- if dgpu_device in PCIIDArray.amd_ids().terascale_1_ids:
- print("- Merging legacy AMD Kexts and Bundles")
- self.delete_old_binaries(ModelArray.DeleteAMDAccel11)
- self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
- self.add_new_binaries(ModelArray.AddAMDAccel11, self.constants.legacy_amd_path)
- self.added_kexts = True
- if self.model in ["MacBookPro8,2", "MacBookPro8,3"]:
- # This is used for MacBookPro8,2/3 where dGPU is disabled via NVRAM and still requires AMD framebuffer
- # For reference:
- #- deMUX: Don't need the AMD patches
- #- dGPUs enabled: Don't install the AMD patches (Infinite login loop otherwise)
- #- dGPUs disabled: Do need the AMD patches (Restores Brightness control)
- dgpu_status: str = subprocess.run("nvram FA4CE28D-B62F-4C99-9CC3-6815686E30F9:gpu-power-prefs".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
- if dgpu_status.startswith("FA4CE28D-B62F-4C99-9CC3-6815686E30F9:gpu-power-prefs %01"):
- print("- Detected dGPU is disabled via NVRAM")
- print("- Merging legacy AMD Kexts and Bundles")
- self.delete_old_binaries(ModelArray.DeleteAMDAccel11)
- self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
- self.add_new_binaries(ModelArray.AddAMDAccel11, self.constants.legacy_amd_path)
- self.added_kexts = True
- else:
- print("- Cannot install Brightness Control, pleas ensure the dGPU is disabled via NVRAM")
- if igpu_vendor:
- print(f"- Found IGPU: {igpu_vendor}:{igpu_device}")
- if igpu_vendor == self.constants.pci_intel:
- if igpu_device in PCIIDArray.intel_ids().iron_ids:
- print("- Merging legacy Intel 1st Gen Kexts and Bundles")
- self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
- self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
- self.add_new_binaries(ModelArray.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path)
- self.added_kexts = True
- elif igpu_device in PCIIDArray.intel_ids().sandy_ids:
- print("- Merging legacy Intel 2nd Gen Kexts and Bundles")
- self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
- self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
- self.add_new_binaries(ModelArray.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path)
- self.added_kexts = True
+ def add_audio_patch(self):
+ self.delete_old_binaries(ModelArray.DeleteVolumeControl)
+ self.add_new_binaries(ModelArray.AddVolumeControl, self.constants.audio_path)
- # TODO: Enable below code if macOS 12 drops support
- # elif igpu_device in PCIIDArray.intel_ids().ivy_ids:
- # print("- Merging legacy Intel 3rd Gen Kexts and Bundles")
- # self.add_new_binaries(ModelArray.AddIntelGen3Accel, self.constants.legacy_intel_gen3_path)
- elif igpu_vendor == self.constants.pci_nvidia:
- if not dgpu_vendor:
- # Avoid patching twice, as Nvidia iGPUs will only have Nvidia dGPUs
- print("- Merging legacy Nvidia Kexts and Bundles")
- self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
- self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
- self.add_new_binaries(ModelArray.AddNvidiaAccel11, self.constants.legacy_nvidia_path)
- self.added_kexts = True
+ def gpu_accel_legacy_nvidia(self):
+ self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
+ self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
+ self.add_new_binaries(ModelArray.AddNvidiaAccel11, self.constants.legacy_nvidia_path)
- if self.added_kexts == True:
- # Frameworks
- print("- Merging legacy Frameworks")
- self.elevated(["ditto", self.constants.payload_apple_frameworks_path_accel, self.mount_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ def gpu_framebuffer_legacy_nvidia(self):
+ self.add_new_binaries(ModelArray.AddNvidiaBrightness, self.constants.legacy_nvidia_path)
- if self.model in ModelArray.LegacyBrightness:
- self.add_brightness_patch()
+ def gpu_accel_legacy_ts1(self):
+ self.delete_old_binaries(ModelArray.DeleteAMDAccel11)
+ self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
+ self.add_new_binaries(ModelArray.AddAMDAccel11, self.constants.legacy_amd_path)
- # LaunchDaemons
- if Path(self.mount_lauchd / Path("HiddHack.plist")).exists():
- print("- Removing legacy HiddHack")
- self.elevated(["rm", f"{self.mount_lauchd}/HiddHack.plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- print("- Adding IOHID-Fixup.plist")
- self.elevated(["ditto", self.constants.payload_apple_lauchd_path_accel, self.mount_lauchd], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- self.elevated(["chmod", "755", f"{self.mount_lauchd}/IOHID-Fixup.plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- self.elevated(["chown", "root:wheel", f"{self.mount_lauchd}/IOHID-Fixup.plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ def gpu_accel_legacy_ts2(self):
+ self.delete_old_binaries(ModelArray.DeleteAMDAccel11)
+ self.delete_old_binaries(ModelArray.DeleteAMDAccel11TS2)
+ self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
+ self.add_new_binaries(ModelArray.AddAMDAccel11, self.constants.legacy_amd_path)
- # PrivateFrameworks
- print("- Merging legacy PrivateFrameworks")
- self.elevated(["ditto", self.constants.payload_apple_private_frameworks_path_accel, self.mount_private_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
- # Sets AppKit to Catalina Window Drawing codepath
- # Disabled upon ASentientBot request
- # print("- Enabling NSDefenestratorModeEnabled")
- # subprocess.run("defaults write -g NSDefenestratorModeEnabled -bool true".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()
- else:
- print("- No Acceleration Kexts were installed, skipping remaining acceleration patches")
+ def gpu_framebuffer_legacy_amd(self):
+ self.add_new_binaries(ModelArray.AddAMDBrightness, self.constants.legacy_amd_path)
+
+ def gpu_accel_legacy_ironlake(self):
+ self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
+ self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
+ self.add_new_binaries(ModelArray.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path)
+
+ def gpu_framebuffer_legacy_ironlake(self):
+ self.add_new_binaries(ModelArray.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path)
+
+ def gpu_accel_legacy_sandybridge(self):
+ self.delete_old_binaries(ModelArray.DeleteNvidiaAccel11)
+ self.add_new_binaries(ModelArray.AddGeneralAccel, self.constants.legacy_general_path)
+ self.add_new_binaries(ModelArray.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path)
+
+ def gpu_framebuffer_legacy_sandybridge(self):
+ self.add_new_binaries(ModelArray.AddIntelGen2Accel, self.constants.legacy_intel_gen1_path)
+
+ def gpu_framebuffer_ivybridge(self):
+ self.delete_old_binaries(ModelArray.DeleteAMDAccel11)
+ self.add_new_binaries(ModelArray.AddIntelGen3Accel, self.constants.legacy_intel_gen3_path)
+ self.elevated(["ditto", self.constants.payload_apple_frameworks_path_accel, self.mount_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+
+ def gpu_accel_legacy_extended(self):
+ print("- Merging general legacy Frameworks")
+ self.elevated(["ditto", self.constants.payload_apple_frameworks_path_accel, self.mount_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ if Path(self.mount_lauchd / Path("HiddHack.plist")).exists():
+ print("- Removing legacy HiddHack")
+ self.elevated(["rm", f"{self.mount_lauchd}/HiddHack.plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ print("- Adding IOHID-Fixup.plist")
+ self.elevated(["ditto", self.constants.payload_apple_lauchd_path_accel, self.mount_lauchd], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ self.elevated(["chmod", "755", f"{self.mount_lauchd}/IOHID-Fixup.plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ self.elevated(["chown", "root:wheel", f"{self.mount_lauchd}/IOHID-Fixup.plist"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ print("- Merging general legacy PrivateFrameworks")
+ self.elevated(["ditto", self.constants.payload_apple_private_frameworks_path_accel, self.mount_private_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+
+ def gpu_accel_legacy_extended_ts2(self):
+ print("- Merging TeraScale 2 legacy Frameworks")
+ self.elevated(["ditto", self.constants.payload_apple_frameworks_path_accel_ts2, self.mount_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
+ print("- Merging TeraScale 2 PrivateFrameworks")
+ self.elevated(["ditto", self.constants.payload_apple_private_frameworks_path_accel_ts2, self.mount_private_frameworks], stdout=subprocess.PIPE).stdout.decode().strip().encode()
def patch_root_vol(self):
- print(f"- Detecting patches for {self.model}")
- rebuild_required = False
- # TODO: Create Backup of S*/L*/Extensions, Frameworks and PrivateFramework to easily revert changes
- # APFS snapshotting seems to ignore System Volume changes inconsistently, would like a backup to avoid total brick
- # Perhaps a basic py2 script to run in recovery to restore
- # Ensures no .DS_Stores got in
- print("- Preparing Files")
- self.elevated(["find", self.constants.payload_apple_root_path, "-name", "'.DS_Store'", "-delete"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
-
- if self.model in ModelArray.LegacyGPU or self.constants.assume_legacy is True:
- dgpu_vendor, dgpu_device, dgpu_acpi = DeviceProbe.pci_probe().gpu_probe("GFX0")
- if (
- dgpu_vendor
- and dgpu_vendor == self.constants.pci_amd_ati
- and (
- dgpu_device in PCIIDArray.amd_ids().polaris_ids
- or dgpu_device in PCIIDArray.amd_ids().vega_ids
- or dgpu_device in PCIIDArray.amd_ids().navi_ids
- or dgpu_device in PCIIDArray.amd_ids().legacy_gcn_ids
- )
- ):
- print("- Detected Metal-based AMD GPU, skipping legacy patches")
- elif dgpu_vendor and dgpu_vendor == self.constants.pci_nvidia and dgpu_device in PCIIDArray.nvidia_ids().kepler_ids:
- print("- Detected Metal-based Nvidia GPU, skipping legacy patches")
+ print(f"- Running patches for {self.model}")
+ # Graphics patches
+ if self.nvidia_legacy is True:
+ print("- Installing legacy Nvidia Patches")
+ if self.constants.detected_os == self.constants.big_sur:
+ print("- Detected Big Sur, installing Acceleration patches")
+ self.gpu_accel_legacy_nvidia()
+ self.added_kexts = True
else:
- print("- Detected legacy GPU, attempting legacy acceleration patches")
- self.gpu_accel_patches_11()
- rebuild_required = True
+ print("- Detected unsupported OS, installing Basic Framebuffer")
+ self.gpu_framebuffer_legacy_nvidia()
- if self.model in ["iMac7,1", "iMac8,1"]:
+ if self.amd_ts1 is True:
+ print("- Installing legacy TeraScale 1 Patches")
+ if self.constants.detected_os == self.constants.big_sur:
+ print("- Detected Big Sur, installing Acceleration patches")
+ self.gpu_accel_legacy_ts1()
+ self.added_kexts = True
+ else:
+ print("- Detected unsupported OS, installing Basic Framebuffer")
+ self.gpu_framebuffer_legacy_amd()
+
+ if self.amd_ts2 is True:
+ print("- Installing legacy TeraScale 2 Patches")
+ if self.constants.detected_os == self.constants.big_sur:
+ print("- Detected Big Sur, installing Acceleration patches")
+ self.gpu_accel_legacy_ts2()
+ self.added_kexts = True
+ else:
+ print("- Detected unsupported OS, installing Basic Framebuffer")
+ self.gpu_framebuffer_legacy_amd()
+
+ if self.iron_gpu is True:
+ print("- Installing legacy Ironlake Patches")
+ if self.constants.detected_os == self.constants.big_sur:
+ print("- Detected Big Sur, installing Acceleration patches")
+ self.gpu_accel_legacy_ironlake()
+ self.added_kexts = True
+ else:
+ print("- Detected unsupported OS, installing Basic Framebuffer")
+ self.gpu_framebuffer_legacy_ironlake()
+
+ if self.sandy_gpu is True:
+ print("- Installing legacy Sandy Bridge Patches")
+ if self.constants.detected_os == self.constants.big_sur:
+ print("- Detected Big Sur, installing Acceleration patches")
+ self.gpu_accel_legacy_sandybridge()
+ self.added_kexts = True
+ else:
+ print("- Detected unsupported OS, installing Basic Framebuffer")
+ self.gpu_framebuffer_legacy_sandybridge()
+
+ if self.ivy_gpu is True:
+ print("- Installing Ivy Bridge Patches")
+ self.gpu_framebuffer_ivybridge()
+
+ if self.amd_ts2 is True:
+ # TeraScale 2 patches must be installed after Intel HD3000
+ self.add_new_binaries(ModelArray.AddAMDAccel11TS2, self.constants.legacy_amd_path_ts2)
+
+ if self.added_kexts is True:
+ self.gpu_accel_legacy_extended()
+ if self.amd_ts2 is True:
+ self.gpu_accel_legacy_extended_ts2()
+
+ # Misc patches
+ if self.brightness_legacy is True:
+ print("- Installing legacy Brightness Control")
+ self.add_brightness_patch()
+
+ if self.legacy_audio is True:
print("- Fixing Volume Control Support")
- self.delete_old_binaries(ModelArray.DeleteVolumeControl)
- self.add_new_binaries(ModelArray.AddVolumeControl, self.constants.audio_path)
- rebuild_required = True
+ self.add_audio_patch()
- if rebuild_required is True:
- self.rebuild_snapshot()
-
- def unpatch_root_vol(self):
- print("- Reverting to last signed APFS snapshot")
- self.elevated(["bless", "--mount", self.mount_location, "--bootefi", "--last-sealed-snapshot"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
-
- def rebuild_snapshot(self):
- if self.constants.gui_mode is False:
- input("Press [ENTER] to continue with cache rebuild")
- print("- Rebuilding Kernel Cache (This may take some time)")
- result = self.elevated(["kmutil", "install", "--volume-root", self.mount_location, "--update-all"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
- if result.returncode != 0:
- self.success_status = False
- print("- Unable to build new kernel cache")
- print("\nPlease report this to Github")
- print("Reason for Patch Failure:")
- print(result.stdout.decode())
- print("")
- else:
- self.success_status = True
- print("- Successfully built new kernel cache")
- if self.constants.gui_mode is False:
- input("Press [ENTER] to continue with snapshotting")
- print("- Creating new APFS snapshot")
- self.elevated(["bless", "--folder", f"{self.mount_location}/System/Library/CoreServices", "--bootefi", "--create-snapshot"], stdout=subprocess.PIPE).stdout.decode().strip().encode()
-
- def unmount_drive(self):
- print("- Unmounting Root Volume (Don't worry if this fails)")
- self.elevated(["diskutil", "unmount", self.root_mount_path], stdout=subprocess.PIPE).stdout.decode().strip().encode()
-
- def check_status(self):
- nvram_dump = plistlib.loads(subprocess.run("nvram -x -p".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode())
- try:
- self.sip_status = nvram_dump["csr-active-config"]
- except KeyError:
- self.sip_status = b"\x00\x00\x00\x00"
-
- self.smb_model: str = subprocess.run("nvram 94B73556-2197-4702-82A8-3E1337DAFBFB:HardwareModel ".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
- if not self.smb_model.startswith("nvram: Error getting variable"):
- self.smb_model = [line.strip().split(":HardwareModel ", 1)[1] for line in self.smb_model.split("\n") if line.strip().startswith("94B73556-2197-4702-82A8-3E1337DAFBFB:")][0]
- if self.smb_model.startswith("j137"):
- self.smb_status = True
- else:
- self.smb_status = False
- else:
- self.smb_status = False
- self.fv_status = True
- if self.constants.recovery_status == False:
- self.fv_status: str = subprocess.run("fdesetup status".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode()
- if self.fv_status.startswith("FileVault is Off"):
- self.fv_status = False
- else:
- # Assume FileVault is off for Recovery purposes
- self.fv_status = False
- self.csr_decode(False)
+ self.rebuild_snapshot()
def check_files(self):
if Path(self.constants.payload_apple_root_path).exists():
@@ -464,79 +336,149 @@ class PatchSysVolume:
print("- Download failed, please verify the below link works:")
print(f"{self.constants.url_apple_binaries}{self.constants.payload_version}")
- def start_patch(self):
- # Check SIP
- # self.check_files()
- if self.constants.custom_model is not None:
- print("Root Patching must be done on target machine!")
- elif self.model in ModelArray.NoRootPatch11 and self.constants.assume_legacy is False:
- print("Root Patching not required for this machine!")
- elif self.model not in ModelArray.SupportedSMBIOS11 and self.constants.assume_legacy is False:
- print("Cannot run on this machine, model is unsupported!")
- elif self.constants.detected_os != self.constants.big_sur:
- print("Cannot run on this OS, requires macOS 11!")
+
+ def detect_gpus(self):
+ igpu_vendor, igpu_device, igpu_acpi = DeviceProbe.pci_probe().gpu_probe("IGPU")
+ dgpu_vendor, dgpu_device, dgpu_acpi = DeviceProbe.pci_probe().gpu_probe("GFX0")
+ if dgpu_vendor:
+ print(f"- Found GFX0: {dgpu_vendor}:{dgpu_device}")
+ if dgpu_vendor == self.constants.pci_nvidia:
+ if dgpu_device in PCIIDArray.nvidia_ids().tesla_ids or dgpu_device in PCIIDArray.nvidia_ids().fermi_ids:
+ if self.constants.detected_os > self.constants.catalina:
+ self.nvidia_legacy = True
+ self.amfi_must_disable = True
+ elif dgpu_vendor == self.constants.pci_amd_ati:
+ if dgpu_device in PCIIDArray.amd_ids().terascale_1_ids:
+ if self.constants.detected_os > self.constants.catalina:
+ self.amd_ts1 = True
+ self.amfi_must_disable = True
+ # TODO: Enable TS2 support
+ elif dgpu_device in PCIIDArray.amd_ids().terascale_2_ids:
+ if self.constants.detected_os > self.constants.catalina:
+ self.amd_ts2 = True
+ self.amfi_must_disable = True
+ if igpu_vendor:
+ print(f"- Found IGPU: {igpu_vendor}:{igpu_device}")
+ if igpu_vendor == self.constants.pci_intel:
+ if igpu_device in PCIIDArray.intel_ids().iron_ids:
+ if self.constants.detected_os > self.constants.catalina:
+ self.iron_gpu = True
+ self.amfi_must_disable = True
+ elif igpu_device in PCIIDArray.intel_ids().sandy_ids:
+ if self.constants.detected_os > self.constants.catalina:
+ self.sandy_gpu = True
+ self.amfi_must_disable = True
+ # TODO: Re-enable when Accel Patches are ready
+ #elif igpu_device in PCIIDArray.intel_ids().ivy_ids:
+ # if self.constants.detected_os > self.constants.big_sur:
+ # self.ivy_gpu = True
+ elif igpu_vendor == self.constants.pci_nvidia:
+ if self.constants.detected_os > self.constants.catalina:
+ self.nvidia_legacy = True
+ self.amfi_must_disable = True
+
+ def detect_patch_set(self):
+ self.detect_gpus()
+ if self.model in ModelArray.LegacyBrightness:
+ if self.constants.detected_os > self.constants.catalina:
+ self.brightness_legacy = True
+
+ if self.model in ["iMac7,1", "iMac8,1"]:
+ if self.constants.detected_os > self.constants.catalina:
+ self.legacy_audio = True
+
+ Utilities.cls()
+ print("The following patches will be applied:")
+ if self.nvidia_legacy is True:
+ print("- Add Legacy Nvidia Tesla Graphics Patch")
+ elif self.amd_ts1 is True:
+ print("- Add Legacy ATI TeraScale 1 Graphics Patch")
+ elif self.amd_ts2 is True:
+ print("- Add Legacy ATI TeraScale 2 Graphics Patch")
+ if self.iron_gpu is True:
+ print("- Add Legacy Intel IronLake Graphics Patch")
+ elif self.sandy_gpu is True:
+ print("- Add Legacy Intel Sandy Bridge Graphics Patch")
+ elif self.ivy_gpu is True:
+ print("- Add Legacy Intel Ivy Bridge Graphics Patch")
+ if self.brightness_legacy is True:
+ print("- Add Legacy Brightness Control")
+ if self.legacy_audio is True:
+ print("- Add legacy Audio Control")
+
+ if self.nvidia_legacy is False and \
+ self.amd_ts1 is False and \
+ self.amd_ts2 is False and \
+ self.iron_gpu is False and \
+ self.sandy_gpu is False and \
+ self.ivy_gpu is False and \
+ self.brightness_legacy is False and \
+ self.legacy_audio is False:
+ self.no_patch = True
else:
- self.check_status()
- Utilities.cls()
- if (self.sip_patch_status is False) and (self.smb_status is False):
- print("- Detected SIP and SecureBootModel are disabled, continuing")
- if self.constants.gui_mode is False:
- input("\nPress [ENTER] to continue")
+ self.no_patch = False
+
+ def verify_patch_allowed(self):
+ self.sip_enabled, self.sbm_enabled, self.amfi_enabled, self.fv_enabled = Utilities.patching_status()
+ if self.sip_enabled is True:
+ print("\nCannot patch!!! Please disable SIP!!!")
+ print("Disable SIP in Patcher Settings and Rebuild OpenCore")
+ print("For Hackintoshes, set SIP to EF0F0000")
+ if self.sbm_enabled is True:
+ print("\nCannot patch!!! Please disable SecureBootModel!!!")
+ print("Disable SecureBootModel in Patcher Settings and Rebuild OpenCore")
+ print("For Hackintoshes, set SecureBootModel to Disabled")
+ if self.fv_enabled is True:
+ print("\nCannot patch!!! Please disable FileVault!!!")
+ print("Go to System Preferences -> Security and disable FileVault")
+
+ if self.amfi_enabled is True and self.amfi_must_disable is True:
+ print("\nCannot patch!!! Please disable AMFI!!!")
+ print("For Hackintoshes, please add amfi_getOut_of_my_way=0x1 to boot-args")
+
+ if self.amfi_must_disable is True:
+ if self.sip_enabled is True or \
+ self.sbm_enabled is True or \
+ self.amfi_enabled is True or \
+ self.fv_enabled is True:
+ return False
+ else:
+ return True
+ else:
+ if self.sip_enabled is True or \
+ self.sbm_enabled is True or \
+ self.fv_enabled is True:
+ return False
+ else:
+ return True
+
+ # Entry Function
+ def start_patch(self):
+ print("- Starting Patch Process")
+ print(f"- Determinging Required Patch set for Darwin {self.constants.detected_os}")
+ self.detect_patch_set()
+ if self.no_patch is False:
+ change_menu = input("Would you like to continue with Root Volume Patching?(y/n): ")
+ else:
+ change_menu = None
+ print("- No Root Patches required for your machine!")
+ input("\nPress [ENTER] to return to the main menu: ")
+ if change_menu in ["y", "Y"]:
+ print("- Continuing with Patching")
+ print("- Verifying whether Root Patching possible")
+ if self.verify_patch_allowed() is True:
+ print("- Patcher is capable of patching")
self.check_files()
- if self.constants.payload_apple_root_path.exists():
- if not self.find_mount_root_vol(True):
- return
- self.unmount_drive()
- print("- Patching complete")
- if self.success_status is True:
- print("\nPlease reboot the machine for patches to take effect")
- else:
- print("\nPlease reboot the machine to avoid potential issues rerunning the patcher")
- if self.sip_patch_status is True:
- print("SIP set incorrectly, cannot patch on this machine!")
- print("Please disable SIP and SecureBootModel in Patcher Settings")
- self.csr_decode(True)
- print("")
- if self.smb_status is True:
- print("SecureBootModel set incorrectly, unable to patch!")
- print("Please disable SecureBootModel in Patcher Settings")
- print("")
- if self.fv_status is True:
- print("FileVault enabled, unable to patch!")
- print("Please disable FileVault in System Preferences")
- print("")
- if self.constants.gui_mode is False:
- input("Press [Enter] to go exit.")
+ self.find_mount_root_vol(True)
+ else:
+ input("\nPress [ENTER] to return to the main menu: ")
+
+ else:
+ print("- Returning to main menu")
def start_unpatch(self):
- if self.constants.custom_model is not None:
- print("Unpatching must be done on target machine!")
- elif self.constants.detected_os != self.constants.big_sur:
- print("Cannot run on this OS, requires macOS 11!")
- else:
- self.check_status()
- Utilities.cls()
- if (self.sip_patch_status is False) and (self.smb_status is False):
- print("- Detected SIP and SecureBootModel are disabled, continuing")
- if self.constants.gui_mode is False:
- input("\nPress [ENTER] to continue")
- if not self.find_mount_root_vol(False):
- return
- self.unmount_drive()
- print("- Unpatching complete")
- print("\nPlease reboot the machine for patches to take effect")
- if self.sip_patch_status is True:
- print("SIP set incorrectly, cannot unpatch on this machine!")
- print("Please disable SIP and SecureBootModel in Patcher Settings")
- self.csr_decode(True)
- print("")
- if self.smb_status is True:
- print("SecureBootModel set incorrectly, unable to unpatch!")
- print("Please disable SecureBootModel in Patcher Settings")
- print("")
- if self.fv_status is True:
- print("FileVault enabled, unable to unpatch!")
- print("Please disable FileVault in System Preferences")
- print("")
- if self.constants.gui_mode is False:
- input("Press [Enter] to go exit.")
+ print("- Starting Unpatch Process")
+ if self.verify_patch_allowed() is True:
+ self.find_mount_root_vol(False)
+ input("\nPress [ENTER] to return to the main menu")
+
diff --git a/payloads/Config/config.plist b/payloads/Config/config.plist
index 08e620f82..c92fb9dc8 100644
--- a/payloads/Config/config.plist
+++ b/payloads/Config/config.plist
@@ -1218,7 +1218,7 @@
SystemAudioVolume
Rg==
boot-args
- keepsyms=1 debug=0x100 -no_compat_check -lilubetaall
+ keepsyms=1 debug=0x100 -lilubetaall
csr-active-config
AAAAAA==