sys_patch.py: Add backend for MetallibSupportPkg

This commit is contained in:
Mykola Grymalyuk
2024-08-28 15:21:35 -06:00
parent a6503bcd97
commit bd51332a17
7 changed files with 448 additions and 19 deletions
@@ -660,13 +660,14 @@ class DetectRootPatch:
"Settings: Requires AMFI exemption": self.amfi_must_disable,
"Settings: Supports Auxiliary Cache": not self.requires_root_kc,
"Settings: Kernel Debug Kit missing": self.missing_kdk if self.os_major >= os_data.os_data.ventura.value else False,
"Settings: MetallibSupportPkg missing": self.os_major >= os_data.os_data.sequoia.value and any([self.kepler_gpu, self.ivy_gpu, self.haswell_gpu]),
"Validation: Patching Possible": self.verify_patch_allowed(),
"Validation: Unpatching Possible": self._verify_unpatch_allowed(),
f"Validation: Unsupported Host OS": self.unsupported_os,
f"Validation: SIP is enabled (Required: {self._check_sip()[2]} or higher)": self.sip_enabled,
f"Validation: Currently Booted SIP: ({hex(py_sip_xnu.SipXnu().get_sip_status().value)})": self.sip_enabled,
"Validation: SecureBootModel is enabled": self.sbm_enabled,
f"Validation: {'AMFI' if self.constants.host_is_hackintosh is True or self._get_amfi_level_needed() > 2 else 'Library Validation'} is enabled": self.amfi_enabled if self.amfi_must_disable is True else False,
f"Validation: {'AMFI' if self.constants.host_is_hackintosh is True or self._get_amfi_level_needed() > 2 else 'Library Validation'} is enabled": self.amfi_enabled if self.amfi_must_disable is True else False,
"Validation: FileVault is enabled": self.fv_enabled,
"Validation: System is dosdude1 patched": self.dosdude_patched,
"Validation: WhateverGreen.kext missing": self.missing_whatever_green if self.nvidia_web is True else False,
@@ -719,9 +720,7 @@ class DetectRootPatch:
return True
if any([self.kepler_gpu, self.ivy_gpu, self.haswell_gpu]):
if Path("~/.dortania_developer").expanduser().exists():
# Temporarily hard coded
if Path("/Library/Application Support/Dortania/MetallibSupportPkg/15.0-24A5327a").exists():
return True
return True
return False
return True
+58 -5
View File
@@ -39,7 +39,8 @@ import logging
import plistlib
import subprocess
from pathlib import Path
from pathlib import Path
from functools import cache
from .mount import (
RootVolumeMount,
@@ -54,12 +55,16 @@ from .utilities import (
from .. import constants
from ..datasets import os_data
from ..volume import generate_copy_arguments
from ..datasets import (
os_data,
sys_patch_dict
)
from ..support import (
utilities,
subprocess_wrapper
subprocess_wrapper,
metallib_handler
)
from . import (
sys_patch_helpers,
@@ -357,7 +362,7 @@ class PatchSysVolume:
)
source_files_path = str(self.constants.payload_local_binaries_root_path)
self._preflight_checks(required_patches, source_files_path)
required_patches = self._preflight_checks(required_patches, source_files_path)
for patch in required_patches:
logging.info("- Installing Patchset: " + patch)
for method_remove in ["Remove", "Remove Non-Root"]:
@@ -429,13 +434,56 @@ class PatchSysVolume:
self._write_patchset(required_patches)
def _preflight_checks(self, required_patches: dict, source_files_path: Path) -> None:
def _resolve_metallib_support_pkg(self) -> str:
"""
Resolves MetalLibSupportPkg
"""
metallib_obj = metallib_handler.MetalLibraryObject(self.constants, self.constants.detected_os_build, self.constants.detected_os_version)
if metallib_obj.success is False:
logging.error(f"Failed to find MetalLibSupportPkg: {metallib_obj.error_msg}")
raise Exception(f"Failed to find MetalLibSupportPkg: {metallib_obj.error_msg}")
metallib_download_obj = metallib_obj.retrieve_download()
if not metallib_download_obj:
# Already downloaded, return path
logging.info(f"Using MetalLibSupportPkg: {metallib_obj.metallib_installed_path}")
return str(metallib_obj.metallib_installed_path)
metallib_download_obj.download(spawn_thread=False)
if metallib_download_obj.download_complete is False:
error_msg = metallib_download_obj.error_msg
logging.error(f"Could not download MetalLibSupportPkg: {error_msg}")
raise Exception(f"Could not download MetalLibSupportPkg: {error_msg}")
if metallib_obj.install_metallib() is False:
logging.error("Failed to install MetalLibSupportPkg")
raise Exception("Failed to install MetalLibSupportPkg")
# After install, check if it's present
return self._resolve_metallib_support_pkg()
@cache
def _resolve_dynamic_patchset(self, variant: sys_patch_dict.DynamicPatchset) -> str:
"""
Resolves dynamic patchset to a path
"""
if variant == sys_patch_dict.DynamicPatchset.MetallibSupportPkg:
return self._resolve_metallib_support_pkg()
raise Exception(f"Unknown Dynamic Patchset: {variant}")
def _preflight_checks(self, required_patches: dict, source_files_path: Path) -> dict:
"""
Runs preflight checks before patching
Parameters:
required_patches (dict): Patchset dictionary (from sys_patch_generate.GenerateRootPatchSets)
source_files_path (Path): Path to the source files (PatcherSupportPkg)
Returns:
dict: Updated patchset dictionary
"""
logging.info("- Running Preflight Checks before patching")
@@ -447,6 +495,9 @@ class PatchSysVolume:
continue
for install_patch_directory in required_patches[patch][method_type]:
for install_file in required_patches[patch][method_type][install_patch_directory]:
if required_patches[patch][method_type][install_patch_directory][install_file] in sys_patch_dict.DynamicPatchset:
required_patches[patch][method_type][install_patch_directory][install_file] = self._resolve_dynamic_patchset(required_patches[patch][method_type][install_patch_directory][install_file])
source_file = required_patches[patch][method_type][install_patch_directory][install_file] + install_patch_directory + "/" + install_file
# Check whether to source from root
@@ -477,6 +528,8 @@ class PatchSysVolume:
logging.info("- Finished Preflight, starting patching")
return required_patches
# Entry Function
def start_patch(self):