Initial Commit

This commit is contained in:
Mykola Grymalyuk
2022-05-02 13:19:36 -06:00
parent 754a6c2a87
commit 4e1254c31e
8 changed files with 608 additions and 906 deletions

View File

@@ -11,8 +11,8 @@ import subprocess
import zipfile
from pathlib import Path
from resources import constants, utilities, generate_smbios, sys_patch_download, sys_patch_detect
from data import sip_data, sys_patch_data, os_data
from resources import constants, generate_smbios, utilities, sys_patch_download, sys_patch_detect
from data import os_data, sys_patch_dict
class PatchSysVolume:
@@ -26,7 +26,7 @@ class PatchSysVolume:
self.root_supports_snapshot = utilities.check_if_root_is_apfs_snapshot()
self.constants.root_patcher_succeded = False # Reset Variable each time we start
# GUI will detect hardware patches betfore starting PatchSysVolume()
# GUI will detect hardware patches before starting PatchSysVolume()
# However the TUI will not, so allow for data to be passed in manually avoiding multiple calls
if hardware_details is None:
hardware_details = sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).detect_patch_set()
@@ -68,14 +68,7 @@ class PatchSysVolume:
else:
self.mount_location = ""
self.mount_location_data = ""
self.mount_coreservices = f"{self.mount_location}/System/Library/CoreServices"
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"
self.mount_private_frameworks = f"{self.mount_location}/System/Library/PrivateFrameworks"
self.mount_libexec = f"{self.mount_location}/usr/libexec"
self.mount_extensions_mux = f"{self.mount_location}/System/Library/Extensions/AppleGraphicsControl.kext/Contents/PlugIns/"
self.mount_private_etc = f"{self.mount_location_data}/private/etc"
self.mount_application_support = f"{self.mount_location_data}/Library/Application Support"
def find_mount_root_vol(self, patch):
@@ -147,6 +140,7 @@ class PatchSysVolume:
# - Check the output for 'KernelCache ID' to see if the cache was successfully rebuilt
# kmutil notes:
# - will return 71 on failure to build KCs
# - will return 31 on 'No binaries or codeless kexts were provided'
# - will return -10 if the volume is missing (ie. unmounted by another process)
if result.returncode != 0 or (self.constants.detected_os < os_data.os_data.catalina and "KernelCache ID" not in result.stdout.decode()):
self.success_status = False
@@ -191,26 +185,7 @@ class PatchSysVolume:
print("- Unmounting Root Volume (Don't worry if this fails)")
utilities.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:
delete_path = Path(self.mount_extensions) / Path(delete_current_kext)
if Path(delete_path).exists():
print(f"- Deleting {delete_current_kext}")
utilities.process_status(utilities.elevated(["rm", "-R", delete_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
print(f"- Couldn't find {delete_current_kext}, skipping")
def add_new_binaries(self, vendor_patch, vendor_location):
for add_current_kext in vendor_patch:
existing_path = Path(self.mount_extensions) / Path(add_current_kext)
if Path(existing_path).exists():
print(f"- Found conflicting kext, Deleting Root Volume's {add_current_kext}")
utilities.process_status(utilities.elevated(["rm", "-R", existing_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
print(f"- Adding {add_current_kext}")
utilities.process_status(utilities.elevated(["cp", "-R", f"{vendor_location}/{add_current_kext}", self.mount_extensions], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/{add_current_kext}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def install_auto_patcher_launch_agent(self):
# Installs the following:
# - OpenCore-Patcher.app in /Library/Application Support/Dortania/
@@ -265,360 +240,192 @@ class PatchSysVolume:
def clean_skylight_plugins(self):
if (Path(self.mount_application_support) / Path("SkyLightPlugins/")).exists():
print("- Found SkylightPlugins folder, removing")
utilities.process_status(utilities.elevated(["rm", "-rf", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def add_brightness_patch(self):
self.delete_old_binaries(sys_patch_data.DeleteBrightness)
self.add_new_binaries(sys_patch_data.AddBrightness, self.constants.legacy_brightness)
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_brightness}/", self.mount_private_frameworks], stdout=subprocess.PIPE)
utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_private_frameworks}/DisplayServices.framework"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_private_frameworks}/DisplayServices.framework"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def add_audio_patch(self):
if self.model in ["iMac7,1", "iMac8,1"]:
self.delete_old_binaries(sys_patch_data.DeleteVolumeControl)
self.add_new_binaries(sys_patch_data.AddVolumeControl, self.constants.audio_path)
print("- Found SkylightPlugins folder, removing old plugins")
utilities.process_status(utilities.elevated(["rm", "-Rf", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["mkdir", f"{self.mount_application_support}/SkyLightPlugins"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
self.add_new_binaries(sys_patch_data.AddVolumeControlv2, self.constants.audio_v2_path)
def add_wifi_patch(self):
print("- Merging Wireless CoreSerices patches")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_coreservices}/", self.mount_coreservices], stdout=subprocess.PIPE)
utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_coreservices}/WiFiAgent.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_coreservices}/WiFiAgent.app"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
print("- Merging Wireless usr/libexec patches")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_libexec}/", self.mount_libexec], stdout=subprocess.PIPE)
utilities.process_status(utilities.elevated(["chmod", "755", f"{self.mount_libexec}/airportd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "root:wheel", f"{self.mount_libexec}/airportd"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
# dylib patch to resolve password crash prompt
# Note requires ASentientBot's SkyLight to function
# Thus Metal machines do not benefit from this patch, however install anyways as harmless
print("- Merging Wireless SkyLightPlugins")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_wifi_support}/", self.mount_application_support], stdout=subprocess.PIPE)
def add_legacy_mux_patch(self):
self.delete_old_binaries(sys_patch_data.DeleteDemux)
print("- Merging Legacy Mux Kext patches")
utilities.process_status(
utilities.elevated(["cp", "-R", f"{self.constants.legacy_mux_path}/AppleMuxControl.kext", self.mount_extensions_mux], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
)
def add_legacy_keyboard_backlight_patch(self):
print("- Enabling Keyboard Backlight delay")
utilities.process_status(
utilities.elevated(["defaults", "write", "/Library/Preferences/.GlobalPreferences.plist", "Moraea_BacklightHack", "-bool", "true"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
)
def add_legacy_dropbox_patch(self):
print("- Merging DropboxHack SkyLightPlugins")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.legacy_dropbox_support}/", self.mount_application_support], stdout=subprocess.PIPE)
def gpu_accel_legacy(self):
if self.constants.detected_os == os_data.os_data.mojave:
print("- Installing General Acceleration Kext patches for Mojave")
self.add_new_binaries(sys_patch_data.AddGeneralAccelMojave, self.constants.legacy_general_path)
elif self.constants.detected_os == os_data.os_data.catalina:
print("- Installing General Acceleration Kext patches for Catalina")
self.add_new_binaries(sys_patch_data.AddGeneralAccelCatalina, self.constants.legacy_general_path)
elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]:
print("- Installing General Acceleration Kext patches for Big Sur/Monterey")
self.add_new_binaries(sys_patch_data.AddGeneralAccel, self.constants.legacy_general_path)
# Nvidia
def gpu_accel_legacy_nvidia_master(self):
if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]:
print("- Installing Nvidia Acceleration Kext patches for Mojave/Catalina")
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddNvidiaAccelLegacy, self.constants.legacy_nvidia_path)
elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]:
print("- Installing Nvidia Acceleration Kext patches for Big Sur/Monterey")
self.delete_old_binaries(sys_patch_data.DeleteNvidiaAccel11)
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddNvidiaAccel11, self.constants.legacy_nvidia_path)
if self.constants.detected_os == os_data.os_data.monterey and self.constants.detected_os_minor > 0:
# Beta 7+ removes NVDAStartup
self.add_new_binaries(sys_patch_data.AddNvidiaTeslaAccel12, self.constants.legacy_nvidia_kepler_path)
else:
print("- Installing basic Nvidia Framebuffer Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddNvidiaBrightness, self.constants.legacy_nvidia_path)
# AMD/ATI
def gpu_accel_legacy_ts1_master(self):
if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]:
print("- Installing TeraScale 1 Acceleration Kext patches for Mojave/Catalina")
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddAMDAccelLegacy, self.constants.legacy_amd_path)
elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]:
print("- Installing TeraScale 1 Acceleration Kext patches for Big Sur/Monterey")
self.delete_old_binaries(sys_patch_data.DeleteAMDAccel11)
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddAMDAccel11, self.constants.legacy_amd_path)
else:
print("- Installing basic TeraScale 1 Framebuffer Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddAMDBrightness, self.constants.legacy_amd_path)
def gpu_accel_legacy_ts2_master(self):
if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina] and self.constants.allow_ts2_accel is True:
print("- Installing TeraScale 2 Acceleration Kext patches for Mojave/Catalina")
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddAMDAccelLegacy, self.constants.legacy_amd_path)
elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey] and self.constants.allow_ts2_accel is True:
print("- Installing TeraScale 2 Acceleration Kext patches for Big Sur")
self.delete_old_binaries(sys_patch_data.DeleteAMDAccel11)
self.delete_old_binaries(sys_patch_data.DeleteAMDAccel11TS2)
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddAMDAccel11, self.constants.legacy_amd_path)
else:
print("- Installing basic TeraScale 2 Framebuffer Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddAMDBrightness, self.constants.legacy_amd_path)
# Intel
def gpu_accel_legacy_ironlake_master(self):
if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]:
print("- Installing Ironlake Acceleration Kext patches for Mojave/Catalina")
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path)
elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]:
print("- Installing Ironlake Acceleration Kext patches for Big Sur/Monterey")
self.delete_old_binaries(sys_patch_data.DeleteNvidiaAccel11)
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path)
else:
print("- Installing basic Ironlake Framebuffer Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddIntelGen1Accel, self.constants.legacy_intel_gen1_path)
def gpu_accel_legacy_sandybridge_master(self):
if self.constants.detected_os in [os_data.os_data.mojave, os_data.os_data.catalina]:
print("- Installing Sandy Bridge Acceleration Kext patches for Mojave/Catalina")
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path)
self.gpu_accel_legacy_sandybridge_board_id()
elif self.constants.detected_os in [os_data.os_data.big_sur, os_data.os_data.monterey]:
print("- Installing Sandy Bridge Acceleration Kext patches for Big Sur/Monterey")
self.delete_old_binaries(sys_patch_data.DeleteNvidiaAccel11)
self.gpu_accel_legacy()
self.add_new_binaries(sys_patch_data.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path)
self.gpu_accel_legacy_sandybridge_board_id()
self.gpu_accel_legacy_gva()
else:
print("- Installing basic Sandy Bridge Framebuffer Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddIntelGen2Accel, self.constants.legacy_intel_gen2_path)
self.gpu_accel_legacy_sandybridge_board_id()
def gpu_accel_legacy_sandybridge_board_id(self):
if self.constants.computer.reported_board_id in self.constants.sandy_board_id_stock:
print("- Using stock AppleIntelSNBGraphicsFB")
# TODO: Clean this function up
# add_new_binaries() and delete_old_binaries() have a bug when the passed array has a single element
# 'TypeError: expected str, bytes or os.PathLike object, not list'
# This is a temporary workaround to fix that
utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB-Clean.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Add kext
print("- Adding AppleIntelSNBGraphicsFB.kext")
utilities.elevated(
["cp", "-r", f"{self.constants.legacy_intel_gen2_path}/AppleIntelSNBGraphicsFB-Clean.kext", f"{self.mount_extensions}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
# Rename kext
utilities.elevated(
["mv", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB-Clean.kext", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
# Fix permissions
utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
# Adjust board ID for spoofs
print("- Using Board ID patched AppleIntelSNBGraphicsFB")
utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB-Clean.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
utilities.elevated(["rm", "-r", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Add kext
print("- Adding AppleIntelSNBGraphicsFB.kext")
utilities.elevated(["cp", "-r", f"{self.constants.legacy_intel_gen2_path}/AppleIntelSNBGraphicsFB.kext", f"{self.mount_extensions}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# Fix permissions
utilities.elevated(["chown", "-Rf", "root:wheel", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
utilities.elevated(["chmod", "-Rf", "755", f"{self.mount_extensions}/AppleIntelSNBGraphicsFB.kext"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def gpu_framebuffer_ivybridge_master(self):
if self.constants.detected_os == os_data.os_data.monterey:
print("- Installing IvyBridge Acceleration Kext patches for Monterey")
self.add_new_binaries(sys_patch_data.AddIntelGen3Accel, self.constants.legacy_intel_gen3_path)
if self.validate is False:
print("- Fixing Acceleration in CoreMedia")
utilities.process_status(subprocess.run(["defaults", "write", "com.apple.coremedia", "hardwareVideoDecoder", "-string", "enable"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
print("- Merging Ivy Bridge Frameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_ivy}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print("- Merging Ivy Bridge PrivateFrameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_accel_ivy}/", self.mount_private_frameworks], stdout=subprocess.PIPE)
else:
print("- Installing basic Ivy Bridge Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddIntelGen3Accel, self.constants.legacy_intel_gen3_path)
def gpu_framebuffer_kepler_master(self):
if self.constants.detected_os == os_data.os_data.monterey:
print("- Installing Kepler Acceleration Kext patches for Monterey")
self.add_new_binaries(sys_patch_data.AddNvidiaKeplerAccel11, self.constants.legacy_nvidia_kepler_path)
print("- Merging Kepler Frameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_kepler}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
print("- Installing Kepler Kext patches for generic OS")
self.add_new_binaries(sys_patch_data.AddNvidiaKeplerAccel11, self.constants.legacy_nvidia_kepler_path)
def gpu_accel_legacy_gva(self):
print("- Merging AppleGVA Hardware Accel patches for non-Metal")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_legacy_drm}/", self.mount_private_frameworks], stdout=subprocess.PIPE)
def gpu_accel_legacy_extended(self):
if self.constants.detected_os == os_data.os_data.monterey:
self.add_legacy_dropbox_patch()
if self.legacy_keyboard_backlight is True:
self.add_legacy_keyboard_backlight_patch()
print("- Merging general legacy Frameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if self.constants.detected_os > os_data.os_data.big_sur:
print("- Merging Monterey WebKit patch")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_ivy}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print("- Merging general legacy PrivateFrameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_accel}/", self.mount_private_frameworks], stdout=subprocess.PIPE)
if self.constants.detected_os > os_data.os_data.catalina:
# With PatcherSupportPkg v0.2.0, IOHID-Fixup.plist is deprecated and integrated into SkyLight patch set
if (Path(self.mount_lauchd) / Path("IOHID-Fixup.plist")).exists():
print("- Stripping legacy IOHID-Fixup.plist")
utilities.process_status(
utilities.elevated(["rm", "-f", f"{self.mount_lauchd}/IOHID-Fixup.plist"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
)
else:
print("- Disabling Library Validation")
utilities.process_status(
utilities.elevated(
["defaults", "write", "/Library/Preferences/com.apple.security.libraryvalidation.plist", "DisableLibraryValidation", "-bool", "true"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
)
def gpu_accel_legacy_extended_ts2(self):
print("- Merging TeraScale 2 legacy Frameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_frameworks_path_accel_ts2}/", self.mount_frameworks], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
print("- Merging TeraScale 2 PrivateFrameworks")
utilities.elevated(["rsync", "-r", "-i", "-a", f"{self.constants.payload_apple_private_frameworks_path_accel_ts2}/", self.mount_private_frameworks], stdout=subprocess.PIPE)
if self.validate is False:
print("- Fixing Acceleration in CMIO")
utilities.process_status(subprocess.run(["defaults", "write", "com.apple.cmio", "CMIO_Unit_Input_ASC.DoNotUseOpenCL", "-bool", "true"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
print("- Creating SkylightPlugins folder")
utilities.process_status(utilities.elevated(["mkdir", f"{self.mount_application_support}/SkyLightPlugins/"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def patch_root_vol(self):
print(f"- Running patches for {self.model}")
# Before starting, clean out old plugins
self.clean_skylight_plugins()
# Graphics patches
if self.nvidia_legacy is True:
print("- Installing legacy Nvidia Patches")
if self.constants.detected_os in self.constants.legacy_accel_support:
print("- Detected supported OS, installing Acceleration Patches")
self.added_legacy_kexts = True
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_accel_legacy_nvidia_master()
elif self.kepler_gpu is True:
print("- Installing Kepler Patches")
if self.constants.detected_os == os_data.os_data.monterey:
print("- Detected supported OS, installing Acceleration Patches")
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_framebuffer_kepler_master()
elif self.amd_ts1 is True:
print("- Installing legacy TeraScale 1 Patches")
if self.constants.detected_os in self.constants.legacy_accel_support:
print("- Detected supported OS, installing Acceleration Patches")
self.added_legacy_kexts = True
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_accel_legacy_ts1_master()
elif self.amd_ts2 is True:
print("- Installing legacy TeraScale 2 Patches")
if self.constants.detected_os in self.constants.legacy_accel_support:
print("- Detected supported OS, installing Acceleration Patches")
self.added_legacy_kexts = True
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_accel_legacy_ts2_master()
if self.iron_gpu is True:
print("- Installing legacy Ironlake Patches")
if self.constants.detected_os in self.constants.legacy_accel_support:
print("- Detected supported OS, installing Acceleration Patches")
self.added_legacy_kexts = True
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_accel_legacy_ironlake_master()
elif self.sandy_gpu is True:
print("- Installing legacy Sandy Bridge Patches")
if self.constants.detected_os in self.constants.legacy_accel_support:
print("- Detected supported OS, installing Acceleration Patches")
self.added_legacy_kexts = True
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_accel_legacy_sandybridge_master()
elif self.ivy_gpu is True:
print("- Installing Ivy Bridge Patches")
if self.constants.detected_os == os_data.os_data.monterey:
print("- Detected supported OS, installing Acceleration Patches")
else:
print("- Detected unsupported OS, installing Basic Framebuffer")
self.gpu_framebuffer_ivybridge_master()
if self.amd_ts2 is True and self.constants.detected_os in self.constants.legacy_accel_support and self.constants.allow_ts2_accel is True:
# TeraScale 2 patches must be installed after Intel HD3000
self.add_new_binaries(sys_patch_data.AddAMDAccel11TS2, self.constants.legacy_amd_path_ts2)
if self.added_legacy_kexts is True and self.constants.detected_os in self.constants.legacy_accel_support:
self.gpu_accel_legacy_extended()
if self.amd_ts2 is True and self.constants.allow_ts2_accel 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.add_audio_patch()
if self.legacy_wifi is True:
print("- Installing legacy Wireless support")
self.add_wifi_patch()
if self.legacy_gmux is True:
print("- Installing Legacy Mux Brightness support")
self.add_legacy_mux_patch()
self.execute_patchset(self.generate_patchset())
if self.constants.wxpython_variant is True and self.constants.detected_os >= os_data.os_data.big_sur:
self.install_auto_patcher_launch_agent()
if self.validate is False:
self.rebuild_snapshot()
self.rebuild_snapshot()
def generate_patchset(self):
all_hardware_patchset = sys_patch_dict.SystemPatchDictionary(self.constants.detected_os)
required_patches = {}
print("- Creating Patch Set for Booted Hardware:")
if self.iron_gpu is True:
print(" - Adding Intel Ironlake Graphics Patchset")
required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]})
required_patches.update({"Intel Ironlake": all_hardware_patchset["Graphics"]["Intel Ironlake"]})
if self.sandy_gpu is True:
print(" - Adding Intel Sandy Bridge Graphics Patchset")
required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]})
required_patches.update({"Legacy GVA": all_hardware_patchset["Graphics"]["Legacy GVA"]})
required_patches.update({"Intel Sandy Bridge": all_hardware_patchset["Graphics"]["Intel Sandy Bridge"]})
if self.ivy_gpu is True:
print(" - Adding Intel Ivy Bridge Graphics Patchset")
required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]})
required_patches.update({"Intel Ivy Bridge": all_hardware_patchset["Graphics"]["Intel Ivy Bridge"]})
if self.nvidia_legacy is True:
print(" - Adding Nvidia Tesla Graphics Patchset")
required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]})
required_patches.update({"Nvidia Tesla": all_hardware_patchset["Graphics"]["Nvidia Tesla"]})
if self.kepler_gpu is True:
print(" - Adding Nvidia Kepler Graphics Patchset")
required_patches.update({"Metal Common": all_hardware_patchset["Graphics"]["Metal Common"]})
required_patches.update({"Nvidia Kepler": all_hardware_patchset["Graphics"]["Nvidia Kepler"]})
if self.amd_ts1 is True:
print(" - Adding AMD TeraScale 1 Graphics Patchset")
required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]})
required_patches.update({"AMD TeraScale 1": all_hardware_patchset["Graphics"]["AMD TeraScale 1"]})
if self.amd_ts2 is True:
print(" - Adding AMD TeraScale 2 Graphics Patchset")
required_patches.update({"Non-Metal Common": all_hardware_patchset["Graphics"]["Non-Metal Common"]})
required_patches.update({"AMD TeraScale 2": all_hardware_patchset["Graphics"]["AMD TeraScale 2"]})
if self.brightness_legacy is True:
print(" - Adding Legacy Brightness Patchset")
required_patches.update({"Legacy Brightness": all_hardware_patchset["Brightness"]["Legacy Brightness"]})
if self.legacy_audio is True:
print(" - Adding Legacy Audio Patchset")
if self.model in ["iMac7,1", "iMac8,1"]:
required_patches.update({"Legacy Realtek": all_hardware_patchset["Audio"]["Legacy Realtek"]})
else:
required_patches.update({"Legacy Non-GOP": all_hardware_patchset["Audio"]["Legacy Non-GOP"]})
if self.legacy_wifi is True:
print(" - Adding Legacy WiFi Patchset")
required_patches.update({"Legacy WiFi": all_hardware_patchset["Networking"]["Legacy WiFi"]})
if self.legacy_gmux is True:
print(" - Adding Legacy GMUX Patchset")
required_patches.update({"Legacy GMUX": all_hardware_patchset["Miscellaneous"]["Legacy GMUX"]})
if self.legacy_keyboard_backlight:
print(" - Adding Legacy Keyboard Backlight Patchset")
required_patches.update({"Legacy Keyboard Backlight": all_hardware_patchset["Miscellaneous"]["Legacy Keyboard Backlight"]})
return required_patches
def execute_patchset(self, required_patches):
source_files_path = str(self.constants.payload_local_binaries_root_path)
print("- Running Preflight Checks before patching")
# Make sure old SkyLight plugins aren't being used
self.clean_skylight_plugins()
# Make sure SNB kexts are compatible with the host
if "Intel Sandy Bridge" in required_patches:
if self.computer.reported_board_id not in self.constants.sandy_board_id_stock:
print(f"- Found unspported Board ID {self.computer.reported_board_id}, performing AppleIntelSNBGraphicsFB bin patching")
board_to_patch = generate_smbios.determine_best_board_id_for_sandy(self.computer.reported_board_id, self.computer.gpus)
print(f"- Replacing {board_to_patch} with {self.computer.reported_board_id}")
board_to_patch_hex = bytes.fromhex(board_to_patch.encode('utf-8').hex())
reported_board_hex = bytes.fromhex(self.computer.reported_board_id.encode('utf-8').hex())
if len(board_to_patch_hex) != len(reported_board_hex):
print(f"- Error: Board ID {self.computer.reported_board_id} is not the same length as {board_to_patch}")
raise Exception("Host's Board ID is not the same length as the kext's Board ID, cannot patch!!!")
else:
path = source_files_path + "10.13.6/System/Library/Extensions/AppleIntelSNBGraphicsFB.kext/Contents/MacOS/AppleIntelSNBGraphicsFB"
if Path(path).exists:
with open(path, 'rb') as f:
data = f.read()
data = data.replace(board_to_patch_hex, reported_board_hex)
with open(path, 'wb') as f:
f.write(data)
else:
raise Exception("Failed to find AppleIntelSNBGraphicsFB.kext, cannot patch!!!")
print("- Finished Preflight, starting patching")
for patch in required_patches:
print("- Installing Patchset: " + patch)
if "Remove" in required_patches[patch]:
for remove_patch_directory in required_patches[patch]["Remove"]:
print("- Remove Files at: " + remove_patch_directory)
for remove_patch_file in required_patches[patch]["Remove"][remove_patch_directory]:
destination_folder_path = str(self.mount_location) + remove_patch_directory
self.remove_file(destination_folder_path, remove_patch_file)
if "Install" in required_patches[patch]:
for install_patch_directory in required_patches[patch]["Install"]:
print(f"- Handling Installs in: {install_patch_directory}")
for install_file in required_patches[patch]["Install"][install_patch_directory]:
source_folder_path = source_files_path + "/" + required_patches[patch]['Install'][install_patch_directory][install_file] + install_patch_directory
destination_folder_path = str(self.mount_location) + install_patch_directory
self.install_new_file(source_folder_path, destination_folder_path, install_file)
if "Install Non-Root" in required_patches[patch]:
for install_patch_directory in required_patches[patch]["Install Non-Root"]:
print(f"- Handling Non-Root Installs in: {install_patch_directory}")
for install_file in required_patches[patch]["Install Non-Root"][install_patch_directory]:
source_folder_path = source_files_path + "/" + required_patches[patch]['Install Non-Root'][install_patch_directory][install_file] + install_patch_directory
destination_folder_path = str(self.mount_location_data) + install_patch_directory
self.install_new_file(source_folder_path, destination_folder_path, install_file)
if "Processes" in required_patches[patch]:
for process in required_patches[patch]["Processes"]:
# Some processes need sudo, however we cannot directly call sudo in some scenarios
# Instead, call elevated funtion and strip sudo from argument
process_array = process.split(" ")
if required_patches[patch]["Processes"][process] is True:
utilities.process_status(utilities.elevated(process_array, stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
utilities.process_status(subprocess.run(process_array, stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def install_new_file(self, source_folder, destination_folder, file_name):
# .frameworks are merged
# .kexts and .apps are deleted and replaced
file_name_str = str(file_name)
if file_name_str.endswith(".kext") or file_name_str.endswith(".app") or file_name_str.endswith(".bundle") or file_name_str.endswith(".plugin"):
if Path(destination_folder + "/" + file_name).exists():
print(f" - Found existing {file_name}, overwritting...")
utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
print(" - Installing: " + file_name)
utilities.process_status(utilities.elevated(["cp", "-R", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
elif file_name_str.endswith(".framework"):
# merge with rsync
print(" - Installing: " + file_name)
utilities.elevated(["rsync", "-r", "-i", "-a", f"{source_folder}/{file_name}", f"{destination_folder}/"], stdout=subprocess.PIPE)
utilities.process_status(utilities.elevated(["chmod", "-Rf", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "-Rf", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
# Assume it's an individual file, replace as normal
if Path(destination_folder + "/" + file_name).exists():
print(f" - Found existing {file_name}, overwritting...")
utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
print(" - Installing: " + file_name)
utilities.process_status(utilities.elevated(["cp", f"{source_folder}/{file_name}", destination_folder], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chmod", "755", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
utilities.process_status(utilities.elevated(["chown", "root:wheel", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def remove_file(self, destination_folder, file_name):
if Path(destination_folder + "/" + file_name).exists():
print(" - Removing: " + file_name)
if Path(destination_folder + "/" + file_name).is_dir():
utilities.process_status(utilities.elevated(["rm", "-R", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
else:
utilities.process_status(utilities.elevated(["rm", f"{destination_folder}/{file_name}"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT))
def check_files(self):
if Path(self.constants.payload_apple_root_path).exists():
if Path(self.constants.payload_local_binaries_root_path).exists():
print("- Found local Apple Binaries")
if self.constants.gui_mode is False:
patch_input = input("Would you like to redownload?(y/n): ")
if patch_input in {"y", "Y", "yes", "Yes"}:
shutil.rmtree(Path(self.constants.payload_apple_root_path))
shutil.rmtree(Path(self.constants.payload_local_binaries_root_path))
output = self.download_files()
else:
output = self.download_files()
@@ -628,32 +435,26 @@ class PatchSysVolume:
def download_files(self):
if self.constants.gui_mode is False or "Library/InstallerSandboxes/" in str(self.constants.payload_path):
download_result, os_ver, extensions_link, framework_link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files()
download_result, os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).download_files()
else:
download_result = True
os_ver, extensions_link, framework_link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link()
os_ver, link = sys_patch_download.grab_patcher_support_pkg(self.constants).generate_pkg_link()
if download_result and self.constants.payload_apple_root_path_zip.exists() and self.constants.payload_universal_extensions_zip_path.exists():
print("- Download completed")
print("- Unzipping download...")
if download_result and self.constants.payload_local_binaries_root_path_zip.exists():
print("- Unzipping binaries...")
try:
utilities.process_status(subprocess.run(["unzip", self.constants.payload_apple_root_path_zip], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.constants.payload_path))
utilities.process_status(subprocess.run(["unzip", self.constants.payload_universal_extensions_zip_path], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.constants.payload_path))
utilities.process_status(subprocess.run(["ditto", "-V", "-x", "-k", "--sequesterRsrc", "--rsrc", self.constants.payload_local_binaries_root_path_zip, self.constants.payload_path]))
print("- Renaming folder")
os.rename(self.constants.payload_path / Path(os_ver), self.constants.payload_apple_root_path)
Path(self.constants.payload_apple_root_path_zip).unlink()
Path(self.constants.payload_universal_extensions_zip_path).unlink()
print("- Binaries downloaded to:")
print(self.constants.payload_path)
return self.constants.payload_apple_root_path
return self.constants.payload_local_binaries_root_path
except zipfile.BadZipFile:
print("- Couldn't unzip")
return None
else:
if self.constants.gui_mode is True:
print("- Download failed, please verify the below links work:")
print(framework_link)
print(extensions_link)
print("- Download failed, please verify the below link work:")
print(link)
print("\nIf you continue to have issues, try using the Offline builds")
print("located on Github next to the other builds")
else:
@@ -705,57 +506,6 @@ class PatchSysVolume:
]
)
def verify_patch_allowed(self):
sip = sip_data.system_integrity_protection.root_patch_sip_big_sur if self.constants.detected_os > os_data.os_data.catalina else sip_data.system_integrity_protection.root_patch_sip_mojave
if sip == sip_data.system_integrity_protection.root_patch_sip_mojave:
sip_value = "For Hackintoshes, please set csr-active-config to '03060000' (0x603)\nFor non-OpenCore Macs, please run 'csrutil disable' in RecoveryOS"
else:
sip_value = (
"For Hackintoshes, please set csr-active-config to '02080000' (0x802)\nFor non-OpenCore Macs, please run 'csrutil disable' and \n'csrutil authenticated-root disable' in RecoveryOS"
)
if self.sip_enabled is True:
print("\nCannot patch! Please disable System Integrity Protection (SIP).")
print("Disable SIP in Patcher Settings and Rebuild OpenCore\n")
print("Ensure the following bits are set for csr-active-config:")
print("\n".join(sip))
print(sip_value)
if self.sbm_enabled is True:
print("\nCannot patch! Please disable Apple Secure Boot.")
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("For OCLP Macs, please rebuild your config with 0.2.5 or newer")
print("For others, 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_get_out_of_my_way=1 to boot-args")
if self.check_board_id is True and (self.computer.reported_board_id not in self.constants.sandy_board_id and self.computer.reported_board_id not in self.constants.sandy_board_id_stock):
print("\nCannot patch! Board ID not supported by AppleIntelSNBGraphicsFB")
print(f"Detected Board ID: {self.computer.reported_board_id}")
print("Please ensure your Board ID is listed below:")
for board in self.constants.sandy_board_id:
print(f"- {board} ({generate_smbios.find_model_off_board(board)})")
for board in self.constants.sandy_board_id_stock:
print(f"- {board} ({generate_smbios.find_model_off_board(board)})")
self.bad_board_id = True
if self.dosdude_patched is True:
print("\nCannot patch! Detected machine has already been patched by another patcher")
print("Please ensure your install is either clean or patched with OpenCore Legacy Patcher")
if any(
[self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched, self.amfi_enabled if self.amfi_must_disable else False, self.bad_board_id if self.check_board_id else False]
):
return False
else:
return True
# Entry Function
def start_patch(self):
print("- Starting Patch Process")
@@ -772,9 +522,8 @@ class PatchSysVolume:
change_menu = "y"
print("- Continuing root patching")
if change_menu in ["y", "Y"]:
print("- Continuing with Patching")
print("- Verifying whether Root Patching possible")
if self.verify_patch_allowed() is True:
if sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).verify_patch_allowed(print_errors=not self.constants.wxpython_variant) is True:
print("- Patcher is capable of patching")
if self.check_files():
self.find_mount_root_vol(True)
@@ -786,7 +535,7 @@ class PatchSysVolume:
def start_unpatch(self):
print("- Starting Unpatch Process")
if self.verify_patch_allowed() is True:
if sys_patch_detect.detect_root_patch(self.computer.real_model, self.constants).verify_patch_allowed(print_errors=not self.constants.wxpython_variant) is True:
self.find_mount_root_vol(False)
if self.constants.gui_mode is False:
input("\nPress [ENTER] to return to the main menu")