diff --git a/devicemanagement/constants.py b/devicemanagement/constants.py
index b88a4b1..20ee020 100644
--- a/devicemanagement/constants.py
+++ b/devicemanagement/constants.py
@@ -13,11 +13,11 @@ class Device:
def supported(self) -> bool:
parsed_ver: Version = Version(self.version)
- if (parsed_ver < Version("17.0")) or (parsed_ver > Version("18.1")):
+ if parsed_ver > Version("18.1"):
return False
if (parsed_ver == Version("18.1")
- and self.build != "22B5007p" and self.build == "22B5023e"
- and self.build == "22B5034e" and self.build == "22B5045g"):
+ and self.build != "22B5007p" and self.build != "22B5023e"
+ and self.build != "22B5034e" and self.build != "22B5045g"):
return False
return True
diff --git a/devicemanagement/device_manager.py b/devicemanagement/device_manager.py
index 02a43a7..c614284 100644
--- a/devicemanagement/device_manager.py
+++ b/devicemanagement/device_manager.py
@@ -99,7 +99,62 @@ class DeviceManager:
return False
else:
return self.data_singleton.current_device.supported()
+
+ def add_skip_setup(self, files_to_restore: list[FileToRestore]):
+ if self.skip_setup and not self.get_current_device_supported():
+ # add the 2 skip setup files
+ cloud_config_plist: dict = {
+ "SkipSetup": ["WiFi", "Location", "Restore", "SIMSetup", "Android", "AppleID", "IntendedUser", "TOS", "Siri", "ScreenTime", "Diagnostics", "SoftwareUpdate", "Passcode", "Biometric", "Payment", "Zoom", "DisplayTone", "MessagingActivationUsingPhoneNumber", "HomeButtonSensitivity", "CloudStorage", "ScreenSaver", "TapToSetup", "Keyboard", "PreferredLanguage", "SpokenLanguage", "WatchMigration", "OnBoarding", "TVProviderSignIn", "TVHomeScreenSync", "Privacy", "TVRoom", "iMessageAndFaceTime", "AppStore", "Safety", "Multitasking", "ActionButton", "TermsOfAddress", "AccessibilityAppearance", "Welcome", "Appearance", "RestoreCompleted", "UpdateCompleted"],
+ "CloudConfigurationUIComplete": True,
+ "IsSupervised": False
+ }
+ files_to_restore.append(FileToRestore(
+ contents=plistlib.dumps(cloud_config_plist),
+ restore_path="systemgroup.com.apple.configurationprofiles/Library/ConfigurationProfiles/CloudConfigurationDetails.plist",
+ domain="SysSharedContainerDomain-."
+ ))
+ purplebuddy_plist: dict = {
+ "SetupDone": True,
+ "SetupFinishedAllSteps": True,
+ "UserChoseLanguage": True
+ }
+ files_to_restore.append(FileToRestore(
+ contents=plistlib.dumps(purplebuddy_plist),
+ restore_path="mobile/com.apple.purplebuddy.plist",
+ domain="ManagedPreferencesDomain"
+ ))
+
+ def get_domain_for_path(self, path: str) -> str:
+ mappings: dict = {
+ "/var/Managed Preferences/": "ManagedPreferencesDomain",
+ "/var/root/": "RootDomain",
+ "/var/preferences/": "SystemPreferencesDomain",
+ "/var/MobileDevice/": "MobileDeviceDomain",
+ "/var/mobile/": "HomeDomain",
+ "/var/db/": "DatabaseDomain",
+ "/var/containers/Shared/SystemGroup/": "SysSharedContainerDomain-.",
+ "/var/containers/Data/SystemGroup/": "SysContainerDomain-."
+ }
+ for mapping in mappings.keys:
+ if path.startswith(mapping):
+ new_path = path.replace(mapping, "")
+ return mappings[mapping], new_path
+ return None, path
+
+ def concat_file(self, contents: str, path: str, files_to_restore: list[FileToRestore]):
+ if self.get_current_device_supported():
+ files_to_restore.append(FileToRestore(
+ contents=contents,
+ restore_path=path
+ ))
+ else:
+ domain, file_path = self.get_domain_for_path(path)
+ files_to_restore.append(FileToRestore(
+ contents=contents,
+ restore_path=file_path,
+ domain=domain
+ ))
## APPLYING OR REMOVING TWEAKS AND RESTORING
def apply_changes(self, resetting: bool = False, update_label=lambda x: None):
@@ -141,34 +196,54 @@ class DeviceManager:
# Generate backup
update_label("Generating backup...")
# create the restore file list
- files_to_restore = [
- FileToRestore(
- contents=plistlib.dumps(flag_plist),
- restore_path="/var/preferences/FeatureFlags/Global.plist",
- )
+ files_to_restore: dict[FileToRestore] = [
]
+ self.concat_file(
+ contents=plistlib.dumps(flag_plist),
+ path="/var/preferences/FeatureFlags/Global.plist",
+ files_to_restore=files_to_restore
+ )
+ self.add_skip_setup(files_to_restore)
if gestalt_data != None:
- files_to_restore.append(FileToRestore(
+ self.concat_file(
contents=gestalt_data,
- restore_path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
- ))
+ path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
+ files_to_restore=files_to_restore
+ )
if eligibility_files:
- files_to_restore += eligibility_files
+ new_eligibility_files: dict[FileToRestore] = []
+ if not self.get_current_device_supported():
+ # update the files
+ for file in eligibility_files:
+ self.concat_file(
+ contents=file.contents,
+ path=file.restore_path,
+ files_to_restore=new_eligibility_files
+ )
+ else:
+ new_eligibility_files = eligibility_files
+ files_to_restore += new_eligibility_files
if ai_file != None:
- files_to_restore.append(ai_file)
+ self.concat_file(
+ contents=ai_file.contents,
+ path=ai_file.restore_path,
+ files_to_restore=files_to_restore
+ )
for location, plist in basic_plists.items():
- files_to_restore.append(FileToRestore(
+ self.concat_file(
contents=plistlib.dumps(plist),
- restore_path=location.value
- ))
+ path=location.value,
+ files_to_restore=files_to_restore
+ )
# reset basic tweaks
if resetting:
empty_data = plistlib.dumps({})
for location in FileLocationsList:
- files_to_restore.append(FileToRestore(
+ self.concat_file(
contents=empty_data,
- restore_path=location.value
- ))
+ path=location.value,
+ files_to_restore=files_to_restore
+ )
# restore to the device
update_label("Restoring to device...")
@@ -194,9 +269,11 @@ class DeviceManager:
# restore to the device
update_label("Restoring to device...")
try:
+ domain, file_path = self.get_domain_for_path("/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist")
restore_files(files=[FileToRestore(
contents=b"",
- restore_path="/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist",
+ restore_path=file_path,
+ domain=domain
)], reboot=True, lockdown_client=self.data_singleton.current_device.ld)
QMessageBox.information(None, "Success!", "All done! Your device will now restart.")
update_label("Success!")
diff --git a/gui/main_window.py b/gui/main_window.py
index 1e86fb8..e4d9b44 100644
--- a/gui/main_window.py
+++ b/gui/main_window.py
@@ -327,8 +327,11 @@ class MainWindow(QtWidgets.QMainWindow):
def show_version_text(self, version: str):
support_str: str = "Supported!"
- if not self.device_manager.get_current_device_supported():
+ if Version(version) < Version("17.0"):
support_str = "Not Supported."
+ elif not self.device_manager.get_current_device_supported():
+ # sparserestore partially patched
+ support_str = "Supported, YMMV."
self.ui.phoneVersionLbl.setText(f"iOS {version} {support_str}")
## HOME PAGE LINKS