amfi_detect.py: Adjust to be more Object-oriented

This commit is contained in:
Mykola Grymalyuk
2023-02-08 15:42:12 -07:00
parent 7be168bf14
commit 7ee631859d
2 changed files with 75 additions and 32 deletions
+71 -28
View File
@@ -1,27 +1,54 @@
# Determine AppleMobileFileIntegrity's OS configuration # Determine AppleMobileFileIntegrity's OS configuration
# Copyright (C) 2022-2023, Mykola Grymalyuk
import enum
from resources import utilities from resources import utilities
class amfi_configuration_detection:
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:
>>> from resources.amfi_detect import AmfiConfigurationDetection
>>> can_patch = AmfiConfigurationDetection().check_config(AmfiConfigDetectLevel.AMFI_LEVEL_ALLOW_ALL)
"""
def __init__(self): def __init__(self):
self.AMFI_ALLOW_TASK_FOR_PID = False self.AMFI_ALLOW_TASK_FOR_PID: bool = False
self.AMFI_ALLOW_INVALID_SIGNATURE = False self.AMFI_ALLOW_INVALID_SIGNATURE: bool = False
self.AMFI_LV_ENFORCE_THIRD_PARTY = False self.AMFI_LV_ENFORCE_THIRD_PARTY: bool = False
self.AMFI_ALLOW_EVERYTHING = False self.AMFI_ALLOW_EVERYTHING: bool = False
self.SKIP_LIBRARY_VALIDATION = False self.SKIP_LIBRARY_VALIDATION: bool = False
self.boot_args = [] self.boot_args: list = []
self.oclp_args = [] self.oclp_args: list = []
self.init_nvram_dicts() self._init_nvram_dicts()
self.parse_amfi_bitmask() self._parse_amfi_bitmask()
self.parse_amfi_boot_args() self._parse_amfi_boot_args()
self.parse_oclp_configuration() self._parse_oclp_configuration()
def init_nvram_dicts(self): def _init_nvram_dicts(self):
"""
Initialize the boot-args and OCLP-Settings NVRAM dictionaries
"""
boot_args = utilities.get_nvram("boot-args", decode=True) boot_args = utilities.get_nvram("boot-args", decode=True)
oclp_args = utilities.get_nvram("OCLP-Settings", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=True) oclp_args = utilities.get_nvram("OCLP-Settings", "4D1FDA02-38C7-4A6A-9CC6-4BCCA8B30102", decode=True)
@@ -32,8 +59,12 @@ class amfi_configuration_detection:
self.oclp_args = oclp_args.split(" ") self.oclp_args = oclp_args.split(" ")
def parse_amfi_bitmask(self): def _parse_amfi_bitmask(self):
# See data/amfi_data.py for more information """
Parse the AMFI bitmask from boot-args
See data/amfi_data.py for more information
"""
amfi_value = 0 amfi_value = 0
for arg in self.boot_args: for arg in self.boot_args:
if arg.startswith("amfi="): if arg.startswith("amfi="):
@@ -65,7 +96,11 @@ class amfi_configuration_detection:
self.AMFI_ALLOW_INVALID_SIGNATURE = True self.AMFI_ALLOW_INVALID_SIGNATURE = True
def parse_amfi_boot_args(self): def _parse_amfi_boot_args(self):
"""
Parse the AMFI boot-args
"""
for arg in self.boot_args: for arg in self.boot_args:
if arg.startswith("amfi_unrestrict_task_for_pid"): if arg.startswith("amfi_unrestrict_task_for_pid"):
value = arg.split("=") value = arg.split("=")
@@ -86,26 +121,34 @@ class amfi_configuration_detection:
self.AMFI_ALLOW_INVALID_SIGNATURE = True self.AMFI_ALLOW_INVALID_SIGNATURE = True
def parse_oclp_configuration(self): def _parse_oclp_configuration(self):
"""
Parse the OCLP configuration
"""
if "-allow_amfi" in self.oclp_args: if "-allow_amfi" in self.oclp_args:
self.SKIP_LIBRARY_VALIDATION = True self.SKIP_LIBRARY_VALIDATION = True
def check_config(self, level): def check_config(self, level: int):
# Levels: """
# - 0: No checks Check the AMFI configuration based on provided AMFI level
# - 1. Library Validation (Monterey and Older) See AmfiConfigLevel enum for valid levels
# - 2. Library Validation and Signature Checks (Ventura and Newer)
# - 3. Disable all AMFI checks
if level == 0: 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 return True
if level == AmfiConfigDetectLevel.LIBRARY_VALIDATION:
if level == 1:
return self.SKIP_LIBRARY_VALIDATION return self.SKIP_LIBRARY_VALIDATION
if level == 2: if level == AmfiConfigDetectLevel.LIBRARY_VALIDATION_AND_SIG:
return bool(self.SKIP_LIBRARY_VALIDATION and self.AMFI_ALLOW_INVALID_SIGNATURE) return bool(self.SKIP_LIBRARY_VALIDATION and self.AMFI_ALLOW_INVALID_SIGNATURE)
if level == 3: if level == AmfiConfigDetectLevel.ALLOW_ALL:
return self.AMFI_ALLOW_EVERYTHING return self.AMFI_ALLOW_EVERYTHING
return False return False
+4 -4
View File
@@ -490,9 +490,9 @@ class detect_root_patch:
if self.amfi_shim_bins is True: if self.amfi_shim_bins is True:
# Currently we require AMFI outright disabled # Currently we require AMFI outright disabled
# in Ventura to work with shim'd binaries # in Ventura to work with shim'd binaries
return 3 return amfi_detect.AmfiConfigDetectLevel.ALLOW_ALL
return 1 return amfi_detect.AmfiConfigDetectLevel.LIBRARY_VALIDATION
return 0 return amfi_detect.AmfiConfigDetectLevel.NO_CHECK
def verify_patch_allowed(self, print_errors=False): def verify_patch_allowed(self, print_errors=False):
sip_dict = self.check_sip() sip_dict = self.check_sip()
@@ -500,7 +500,7 @@ class detect_root_patch:
sip_value = sip_dict[1] sip_value = sip_dict[1]
self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched = utilities.patching_status(sip, self.constants.detected_os) self.sip_enabled, self.sbm_enabled, self.fv_enabled, self.dosdude_patched = utilities.patching_status(sip, self.constants.detected_os)
self.amfi_enabled = not amfi_detect.amfi_configuration_detection().check_config(self.get_amfi_level_needed()) self.amfi_enabled = not amfi_detect.AmfiConfigurationDetection().check_config(self.get_amfi_level_needed())
if self.nvidia_web is True: if self.nvidia_web is True:
self.missing_nv_web_nvram = not self.check_nv_web_nvram() self.missing_nv_web_nvram = not self.check_nv_web_nvram()