#!/usr/bin/env python3 # Copyright (C) 2020-2021 Mykola Grymalyuk from __future__ import print_function import binascii import plistlib import subprocess import sys import time import platform import argparse from pathlib import Path from Resources import Build, ModelArray, Constants, SysPatch, Utilities, CliMenu class OpenCoreLegacyPatcher(): def __init__(self): self.constants = Constants.Constants() self.current_model: str = None opencore_model: str = subprocess.run("nvram 4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:oem-product".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode() if not opencore_model.startswith("nvram: Error getting variable"): opencore_model = [line.strip().split(":oem-product ", 1)[1] for line in opencore_model.split("\n") if line.strip().startswith("4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102:")][0] self.current_model = opencore_model else: self.current_model = subprocess.run("system_profiler SPHardwareDataType".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) self.current_model = [line.strip().split(": ", 1)[1] for line in self.current_model.stdout.decode().split("\n") if line.strip().startswith("Model Identifier")][0] self.constants.detected_os = int(platform.uname().release.partition(".")[0]) if self.current_model in ModelArray.NoAPFSsupport: self.constants.serial_settings = "Moderate" if self.current_model in ModelArray.LegacyGPU: try: dgpu_devices = plistlib.loads(subprocess.run("ioreg -r -n GFX0 -a".split(), stdout=subprocess.PIPE).stdout.decode().strip().encode()) dgpu_vendor = self.hexswap(binascii.hexlify(dgpu_devices[0]["vendor-id"]).decode()[:4]) dgpu_device = self.hexswap(binascii.hexlify(dgpu_devices[0]["device-id"]).decode()[:4]) except ValueError: dgpu_vendor = "" dgpu_device = "" if (dgpu_vendor == self.constants.pci_amd_ati and dgpu_device in ModelArray.AMDMXMGPUs) or (dgpu_vendor == self.constants.pci_nvidia and dgpu_device in ModelArray.NVIDIAMXMGPUs): self.constants.sip_status = True self.constants.secure_status = True else: self.constants.sip_status = False self.constants.secure_status = False # Logic for when user runs custom OpenCore build and do not expose it # Note: This logic currently only applies for iMacPro1,1 users, see below threads on the culprits: # - https://forums.macrumors.com/threads/2011-imac-graphics-card-upgrade.1596614/post-17425857 # - https://forums.macrumors.com/threads/opencore-on-the-mac-pro.2207814/ # PLEASE FOR THE LOVE OF GOD JUST SET ExposeSensitiveData CORRECTLY!!! if self.current_model == "iMacPro1,1": serial: str = subprocess.run("system_profiler SPHardwareDataType | grep Serial".split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.decode() serial = [line.strip().split("Number (system): ", 1)[1] for line in serial.split("\n") if line.strip().startswith("Serial")][0] true_model = subprocess.run([str(self.constants.macserial_path), "--info", str(serial)], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) true_model = [i.partition(" - ")[2] for i in true_model.stdout.decode().split("\n") if "Model: " in i][0] print(f"True Model: {true_model}") if not true_model.startswith("Unknown"): self.current_model = true_model parser = argparse.ArgumentParser() # Generic building args parser.add_argument('--build', help='Build OpenCore', action='store_true', required=False) parser.add_argument('--verbose', help='Enable verbose boot', action='store_true', required=False) parser.add_argument('--debug_oc', help='Enable OpenCore DEBUG', action='store_true', required=False) parser.add_argument('--debug_kext', help='Enable kext DEBUG', action='store_true', required=False) parser.add_argument('--skip_wifi', help='Skip wifi patches', action='store_true', required=False) parser.add_argument('--hide_picker', help='Hide OpenCore picker', action='store_true', required=False) parser.add_argument('--disable_sip', help='Disable SIP', action='store_true', required=False) parser.add_argument('--disable_smb', help='Disable SecureBootModel', action='store_true', required=False) parser.add_argument('--vault', help='Enable OpenCore Vaulting', action='store_true', required=False) parser.add_argument('--support_all', help='Allow OpenCore on natively supported Models', action='store_true', required=False) parser.add_argument('--force_legacy', help='Allow acceleration on Mac Pros and Xserves', action='store_true', required=False) # Building args requiring value values parser.add_argument('--model', action='store', help='Set custom model', required=False) parser.add_argument('--metal_gpu', action='store', help='Set Metal GPU Vendor', required=False) parser.add_argument('--smbios_spoof', action='store', help='Set SMBIOS patching mode', required=False) # SysPatch args parser.add_argument('--patch_sys_vol', help='Patches root volume', action='store_true', required=False) parser.add_argument('--unpatch_sys_vol', help='Unpatches root volume, EXPERIMENTAL', action='store_true', required=False) args = parser.parse_args() self.constants.gui_mode = True self.constants.current_path = Path.cwd() if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): print("- Rerouting payloads location") self.constants.payload_path = sys._MEIPASS / Path("payloads") else: print("- Using default payloads location") if args.verbose: print("- Set verbose configuration") self.constants.verbose_debug = True if args.debug_oc: print("- Set OpenCore DEBUG configuration") self.constants.opencore_debug = True self.constants.opencore_build = "DEBUG" if args.debug_kext: print("- Set kext DEBUG configuration") self.constants.kext_debug = True if args.skip_wifi: print("- Set wifi skip configuration") self.constants.wifi_build = True if args.hide_picker: print("- Set HidePicker configuration") self.constants.showpicker = False if args.disable_sip: print("- Set Disable SIP configuration") self.constants.sip_status = False if args.disable_smb: print("- Set Disable SecureBootModel configuration") self.constants.secure_status = False if args.vault: print("- Set Vault configuration") self.constants.vault = True if args.metal_gpu: if args.metal_gpu == "Nvidia": print("- Set Metal GPU patches to Nvidia") self.constants.metal_build = True self.constants.imac_vendor = "Nvidia" elif args.metal_gpu == "AMD": print("- Set Metal GPU patches to AMD") self.constants.metal_build = True self.constants.imac_vendor = "AMD" else: print(f"- Unknown GPU arg passed: {args.metal_gpu}") self.constants.metal_build = False self.constants.imac_vendor = "None" if args.smbios_spoof: if args.smbios_spoof == "Minimal": self.constants.serial_settings = "Minimal" elif args.smbios_spoof == "Moderate": self.constants.serial_settings = "Moderate" elif args.smbios_spoof == "Advanced": self.constants.serial_settings = "Advanced" else: print(f"- Unknown SMBIOS arg passed: {args.smbios_spoof}") if args.support_all: print("- Building for natively supported model") self.constants.allow_oc_everywhere = True self.constants.serial_settings = "None" if args.force_legacy: print("- Allowing legacy acceleration patches on newer models") self.constants.assume_legacy = True if args.build: if args.model: print(f"- Using custom model: {args.model}") self.constants.custom_model = args.model self.build_opencore() else: print(f"- Using detected model: {self.current_model}") self.build_opencore() if args.patch_sys_vol: print("- Set System Volume patching") self.patch_vol() elif args.unpatch_sys_vol: print("- Set System Volume unpatching") self.unpatch_vol() def hexswap(self, input_hex: str): hex_pairs = [input_hex[i:i + 2] for i in range(0, len(input_hex), 2)] hex_rev = hex_pairs[::-1] hex_str = "".join(["".join(x) for x in hex_rev]) return hex_str.upper() def patch_vol(self): SysPatch.PatchSysVolume(self.constants.custom_model or self.current_model, self.constants).start_patch() def unpatch_vol(self): SysPatch.PatchSysVolume(self.constants.custom_model or self.current_model, self.constants).start_unpatch() def build_opencore(self): Build.BuildOpenCore(self.constants.custom_model or self.current_model, self.constants).build_opencore() def install_opencore(self): Build.BuildOpenCore(self.constants.custom_model or self.current_model, self.constants).copy_efi() OpenCoreLegacyPatcher() # Example arg for OCLP command line # ./OCLP-CLI --build --verbose --debug_oc --debug_kext --model iMac11,2