sys_patch_detect: Revise AMFI logic

Currently the AMFI level requirement will be determined by the GPU needed.
- Intel iGPUs: Only Library Validation patch (`_cs_require_lv`)
- Nvidia Kepler and GCN: Full AMFI needs to be disabled (`amfi=0x80`)

If you have a mixed GPU system, the highest patch requirement will be chosen (ie. `amfi=0x80` on iMac15,1)
This commit is contained in:
Mykola Grymalyuk
2022-09-14 07:57:41 -06:00
parent 7fc2d478f2
commit 012a629100
3 changed files with 42 additions and 16 deletions

View File

@@ -95,13 +95,16 @@ class amfi_configuration_detection:
# Levels: # Levels:
# - 1. Library Validation (Monterey and Older) # - 1. Library Validation (Monterey and Older)
# - 2. Library Validation and Signature Checks (Ventura and Newer) # - 2. Library Validation and Signature Checks (Ventura and Newer)
# - 3. Disable all AMFI checks
if level > 2 or level < 1: if level == 0:
raise ValueError("Invalid AMFI Configuration Level") return True
if level == 1: if level == 1:
return self.SKIP_LIBRARY_VALIDATION return self.SKIP_LIBRARY_VALIDATION
if level == 2: if level == 2:
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:
return self.AMFI_ALLOW_EVERYTHING
return False return False

View File

@@ -4,7 +4,7 @@
# Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk # Copyright (C) 2020-2022, Dhinak G, Mykola Grymalyuk
import subprocess import subprocess
from resources import constants, device_probe, utilities, sys_patch_helpers from resources import constants, device_probe, utilities, sys_patch_helpers, amfi_detect
from data import model_array, os_data, sip_data, sys_patch_dict from data import model_array, os_data, sip_data, sys_patch_dict
class detect_root_patch: class detect_root_patch:
@@ -36,6 +36,7 @@ class detect_root_patch:
# Patch Requirements # Patch Requirements
self.amfi_must_disable = False self.amfi_must_disable = False
self.amfi_shim_bins = False
self.supports_metal = False self.supports_metal = False
self.needs_nv_web_checks = False self.needs_nv_web_checks = False
self.requires_root_kc = False self.requires_root_kc = False
@@ -63,6 +64,7 @@ class detect_root_patch:
if self.constants.detected_os > non_metal_os: if self.constants.detected_os > non_metal_os:
self.nvidia_tesla = True self.nvidia_tesla = True
self.amfi_must_disable = True self.amfi_must_disable = True
self.amfi_shim_bins = True
self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight() self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight()
self.requires_root_kc = True self.requires_root_kc = True
elif gpu.arch == device_probe.NVIDIA.Archs.Kepler and self.constants.force_nv_web is False: elif gpu.arch == device_probe.NVIDIA.Archs.Kepler and self.constants.force_nv_web is False:
@@ -81,7 +83,9 @@ class detect_root_patch:
): ):
self.kepler_gpu = True self.kepler_gpu = True
self.supports_metal = True self.supports_metal = True
self.amfi_must_disable = True if self.constants.detected_os > os_data.os_data.ventura:
self.amfi_must_disable = True
self.amfi_shim_bins = True
elif gpu.arch in [ elif gpu.arch in [
device_probe.NVIDIA.Archs.Fermi, device_probe.NVIDIA.Archs.Fermi,
device_probe.NVIDIA.Archs.Kepler, device_probe.NVIDIA.Archs.Kepler,
@@ -91,17 +95,20 @@ class detect_root_patch:
if self.constants.detected_os > os_data.os_data.mojave: if self.constants.detected_os > os_data.os_data.mojave:
self.nvidia_web = True self.nvidia_web = True
self.amfi_must_disable = True self.amfi_must_disable = True
self.amfi_shim_bins = True
self.needs_nv_web_checks = True self.needs_nv_web_checks = True
self.requires_root_kc = True self.requires_root_kc = True
elif gpu.arch == device_probe.AMD.Archs.TeraScale_1: elif gpu.arch == device_probe.AMD.Archs.TeraScale_1:
if self.constants.detected_os > non_metal_os: if self.constants.detected_os > non_metal_os:
self.amd_ts1 = True self.amd_ts1 = True
self.amfi_must_disable = True self.amfi_must_disable = True
self.amfi_shim_bins = True
self.requires_root_kc = True self.requires_root_kc = True
elif gpu.arch == device_probe.AMD.Archs.TeraScale_2: elif gpu.arch == device_probe.AMD.Archs.TeraScale_2:
if self.constants.detected_os > non_metal_os: if self.constants.detected_os > non_metal_os:
self.amd_ts2 = True self.amd_ts2 = True
self.amfi_must_disable = True self.amfi_must_disable = True
self.amfi_shim_bins = True
self.requires_root_kc = True self.requires_root_kc = True
elif gpu.arch in [ elif gpu.arch in [
device_probe.AMD.Archs.Legacy_GCN_7000, device_probe.AMD.Archs.Legacy_GCN_7000,
@@ -115,34 +122,46 @@ class detect_root_patch:
self.legacy_gcn = True self.legacy_gcn = True
self.supports_metal = True self.supports_metal = True
self.requires_root_kc = True self.requires_root_kc = True
self.amfi_must_disable = True if self.constants.detected_os > os_data.os_data.ventura:
self.amfi_must_disable = True
self.amfi_shim_bins = True
elif gpu.arch == device_probe.Intel.Archs.Iron_Lake: elif gpu.arch == device_probe.Intel.Archs.Iron_Lake:
if self.constants.detected_os > non_metal_os: if self.constants.detected_os > non_metal_os:
self.iron_gpu = True self.iron_gpu = True
self.amfi_must_disable = True self.amfi_must_disable = True
self.amfi_shim_bins = True
self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight() self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight()
self.requires_root_kc = True self.requires_root_kc = True
elif gpu.arch == device_probe.Intel.Archs.Sandy_Bridge: elif gpu.arch == device_probe.Intel.Archs.Sandy_Bridge:
if self.constants.detected_os > non_metal_os: if self.constants.detected_os > non_metal_os:
self.sandy_gpu = True self.sandy_gpu = True
self.amfi_must_disable = True self.amfi_must_disable = True
self.amfi_shim_bins = True
self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight() self.legacy_keyboard_backlight = self.check_legacy_keyboard_backlight()
self.requires_root_kc = True self.requires_root_kc = True
elif gpu.arch == device_probe.Intel.Archs.Ivy_Bridge: elif gpu.arch == device_probe.Intel.Archs.Ivy_Bridge:
if self.constants.detected_os > os_data.os_data.big_sur: if self.constants.detected_os > os_data.os_data.big_sur:
self.ivy_gpu = True self.ivy_gpu = True
if self.constants.detected_os > os_data.os_data.ventura:
self.amfi_must_disable = True
self.supports_metal = True self.supports_metal = True
elif gpu.arch == device_probe.Intel.Archs.Haswell: elif gpu.arch == device_probe.Intel.Archs.Haswell:
if self.constants.detected_os > os_data.os_data.monterey: if self.constants.detected_os > os_data.os_data.monterey:
self.haswell_gpu = True self.haswell_gpu = True
if self.constants.detected_os > os_data.os_data.ventura:
self.amfi_must_disable = True
self.supports_metal = True self.supports_metal = True
elif gpu.arch == device_probe.Intel.Archs.Broadwell: elif gpu.arch == device_probe.Intel.Archs.Broadwell:
if self.constants.detected_os > os_data.os_data.monterey: if self.constants.detected_os > os_data.os_data.monterey:
self.broadwell_gpu = True self.broadwell_gpu = True
if self.constants.detected_os > os_data.os_data.ventura:
self.amfi_must_disable = True
self.supports_metal = True self.supports_metal = True
elif gpu.arch == device_probe.Intel.Archs.Skylake: elif gpu.arch == device_probe.Intel.Archs.Skylake:
if self.constants.detected_os > os_data.os_data.monterey: if self.constants.detected_os > os_data.os_data.monterey:
self.skylake_gpu = True self.skylake_gpu = True
if self.constants.detected_os > os_data.os_data.ventura:
self.amfi_must_disable = True
self.supports_metal = True self.supports_metal = True
if self.supports_metal is True: if self.supports_metal is True:
# Avoid patching Metal and non-Metal GPUs if both present, prioritize Metal GPU # Avoid patching Metal and non-Metal GPUs if both present, prioritize Metal GPU
@@ -320,12 +339,25 @@ class detect_root_patch:
return self.root_patch_dict return self.root_patch_dict
def get_amfi_level_needed(self):
if self.amfi_must_disable is True:
if self.constants.detected_os > os_data.os_data.catalina:
if self.constants.detected_os >= os_data.os_data.ventura:
if self.amfi_shim_bins is True:
# Currently we require AMFI outright disabled
# in Ventura to work with shim'd binaries
return 3
return 1
return 0
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()
sip = sip_dict[0] sip = sip_dict[0]
sip_value = sip_dict[1] sip_value = sip_dict[1]
self.sip_enabled, self.sbm_enabled, self.amfi_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 = amfi_detect.amfi_configuration_detection().check_config(self.get_amfi_level_needed())
if self.requires_root_kc is True: if self.requires_root_kc is True:
self.missing_kdk = not self.check_kdk() self.missing_kdk = not self.check_kdk()

View File

@@ -250,21 +250,12 @@ def patching_status(os_sip, os):
# Detection for Root Patching # Detection for Root Patching
sip_enabled = True # System Integrity Protection sip_enabled = True # System Integrity Protection
sbm_enabled = True # Secure Boot Status (SecureBootModel) sbm_enabled = True # Secure Boot Status (SecureBootModel)
amfi_enabled = True # Apple Mobile File Integrity
fv_enabled = True # FileVault fv_enabled = True # FileVault
dosdude_patched = True dosdude_patched = True
gen6_kext = "/System/Library/Extension/AppleIntelHDGraphics.kext" gen6_kext = "/System/Library/Extension/AppleIntelHDGraphics.kext"
gen7_kext = "/System/Library/Extension/AppleIntelHD3000Graphics.kext" gen7_kext = "/System/Library/Extension/AppleIntelHD3000Graphics.kext"
if os > os_data.os_data.catalina:
amfi_level = 1
if os >= os_data.os_data.ventura:
amfi_level = 2
amfi_enabled = not amfi_detect.amfi_configuration_detection().check_config(amfi_level)
else:
# Catalina and older supports individually disabling Library Validation
amfi_enabled = False
sbm_enabled = check_secure_boot_level() sbm_enabled = check_secure_boot_level()
@@ -284,7 +275,7 @@ def patching_status(os_sip, os):
if not (Path(gen6_kext).exists() and Path(gen7_kext).exists()): if not (Path(gen6_kext).exists() and Path(gen7_kext).exists()):
dosdude_patched = False dosdude_patched = False
return sip_enabled, sbm_enabled, amfi_enabled, fv_enabled, dosdude_patched return sip_enabled, sbm_enabled, fv_enabled, dosdude_patched
clear = True clear = True