Files
OpenCore-Legacy-Patcher/resources/amfi_detect.py
2023-03-19 11:24:24 -06:00

154 lines
5.1 KiB
Python

# Determine AppleMobileFileIntegrity's OS configuration
# Copyright (C) 2022-2023, Mykola Grymalyuk
import enum
from resources import utilities
from data import amfi_data
class AmfiConfigDetectLevel(enum.IntEnum):
"""
Configuration levels used by AmfiConfigurationDetection
"""
NO_CHECK: int = 0
LIBRARY_VALIDATION: int = 1 # For Ventura, use LIBRARY_VALIDATION_AND_SIG
LIBRARY_VALIDATION_AND_SIG: int = 2
ALLOW_ALL: int = 3
class AmfiConfigurationDetection:
"""
Detect AppleMobileFileIntegrity's OS configuration
Usage:
>>> import amfi_detect
>>> can_patch = amfi_detect.AmfiConfigurationDetection().check_config(amfi_detect.AmfiConfigDetectLevel.ALLOW_ALL)
"""
def __init__(self) -> None:
self.AMFI_ALLOW_TASK_FOR_PID: bool = False
self.AMFI_ALLOW_INVALID_SIGNATURE: bool = False
self.AMFI_LV_ENFORCE_THIRD_PARTY: bool = False
self.AMFI_ALLOW_EVERYTHING: bool = False
self.SKIP_LIBRARY_VALIDATION: bool = False
self.boot_args: list = []
self.oclp_args: list = []
self._init_nvram_dicts()
self._parse_amfi_bitmask()
self._parse_amfi_boot_args()
self._parse_oclp_configuration()
def _init_nvram_dicts(self) -> None:
"""
Initialize the boot-args and OCLP-Settings NVRAM dictionaries
"""
boot_args = utilities.get_nvram("boot-args", decode=True)
oclp_args = utilities.get_nvram("OCLP-Settings", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=True)
if boot_args:
self.boot_args = boot_args.split(" ")
if oclp_args:
self.oclp_args = oclp_args.split(" ")
def _parse_amfi_bitmask(self) -> None:
"""
Parse the AMFI bitmask from boot-args
See data/amfi_data.py for more information
"""
amfi_value = 0
for arg in self.boot_args:
if not arg.startswith("amfi="):
continue
try:
amfi_value = arg.split("=")
if len(amfi_value) != 2:
return
amfi_value = amfi_value[1]
if amfi_value.startswith("0x"):
amfi_value = int(amfi_value, 16)
else:
amfi_value = int(amfi_value)
except:
return
break
if amfi_value == 0:
return
self.AMFI_ALLOW_TASK_FOR_PID: bool = amfi_value & amfi_data.AppleMobileFileIntegrity.AMFI_ALLOW_TASK_FOR_PID
self.AMFI_ALLOW_INVALID_SIGNATURE: bool = amfi_value & amfi_data.AppleMobileFileIntegrity.AMFI_ALLOW_INVALID_SIGNATURE
self.AMFI_LV_ENFORCE_THIRD_PARTY: bool = amfi_value & amfi_data.AppleMobileFileIntegrity.AMFI_LV_ENFORCE_THIRD_PARTY
if amfi_value & amfi_data.AppleMobileFileIntegrity.AMFI_ALLOW_EVERYTHING:
self.AMFI_ALLOW_EVERYTHING = True
self.SKIP_LIBRARY_VALIDATION = True
self.AMFI_ALLOW_INVALID_SIGNATURE = True
def _parse_amfi_boot_args(self) -> None:
"""
Parse the AMFI boot-args
"""
for arg in self.boot_args:
if arg.startswith("amfi_unrestrict_task_for_pid"):
value = arg.split("=")
if len(value) == 2:
if value[1] in ["0x1", "1"]:
self.AMFI_ALLOW_TASK_FOR_PID = True
elif arg.startswith("amfi_allow_any_signature"):
value = arg.split("=")
if len(value) == 2:
if value[1] in ["0x1", "1"]:
self.AMFI_ALLOW_INVALID_SIGNATURE = True
elif arg.startswith("amfi_get_out_of_my_way"):
value = arg.split("=")
if len(value) == 2:
if value[1] in ["0x1", "1"]:
self.AMFI_ALLOW_EVERYTHING = True
self.SKIP_LIBRARY_VALIDATION = True
self.AMFI_ALLOW_INVALID_SIGNATURE = True
def _parse_oclp_configuration(self) -> None:
"""
Parse the OCLP configuration
"""
if "-allow_amfi" in self.oclp_args:
self.SKIP_LIBRARY_VALIDATION = True
def check_config(self, level: int) -> bool:
"""
Check the AMFI configuration based on provided AMFI level
See AmfiConfigLevel enum for valid levels
Parameters:
level (int): The level of AMFI checks to check for
Returns:
bool: True if the AMFI configuration matches the level, False otherwise
"""
if level == AmfiConfigDetectLevel.NO_CHECK:
return True
if level == AmfiConfigDetectLevel.LIBRARY_VALIDATION:
return self.SKIP_LIBRARY_VALIDATION
if level == AmfiConfigDetectLevel.LIBRARY_VALIDATION_AND_SIG:
return bool(self.SKIP_LIBRARY_VALIDATION and self.AMFI_ALLOW_INVALID_SIGNATURE)
if level == AmfiConfigDetectLevel.ALLOW_ALL:
return self.AMFI_ALLOW_EVERYTHING
return False