mirror of
https://github.com/leminlimez/Nugget.git
synced 2025-04-08 04:23:05 +08:00
handle app bundle during restore
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
from . import backup, perform_restore
|
from . import backup, perform_restore
|
||||||
from pymobiledevice3.lockdown import LockdownClient
|
from pymobiledevice3.lockdown import LockdownClient
|
||||||
|
from pymobiledevice3.services.installation_proxy import InstallationProxyService
|
||||||
import os
|
import os
|
||||||
|
|
||||||
class FileToRestore:
|
class FileToRestore:
|
||||||
@@ -10,13 +11,6 @@ class FileToRestore:
|
|||||||
self.owner = owner
|
self.owner = owner
|
||||||
self.group = group
|
self.group = group
|
||||||
|
|
||||||
class AppBundleToRestore(FileToRestore):
|
|
||||||
def __init__(self, bundle_id: str, bundle_version: str, bundle_path: str, container_content_class: str):
|
|
||||||
super().__init__(contents=None, restore_path=bundle_path, domain=f"AppDomain-{bundle_id}")
|
|
||||||
self.bundle_id = bundle_id
|
|
||||||
self.bundle_version = bundle_version
|
|
||||||
self.container_content_class = container_content_class
|
|
||||||
|
|
||||||
def concat_exploit_file(file: FileToRestore, files_list: list[FileToRestore], last_domain: str) -> str:
|
def concat_exploit_file(file: FileToRestore, files_list: list[FileToRestore], last_domain: str) -> str:
|
||||||
base_path = "/var/backup"
|
base_path = "/var/backup"
|
||||||
# set it to work in the separate volumes (prevents a bootloop)
|
# set it to work in the separate volumes (prevents a bootloop)
|
||||||
@@ -91,25 +85,33 @@ def restore_files(files: list, reboot: bool = False, lockdown_client: LockdownCl
|
|||||||
files_list = [
|
files_list = [
|
||||||
]
|
]
|
||||||
apps_list = []
|
apps_list = []
|
||||||
|
active_bundle_ids = []
|
||||||
|
apps = None
|
||||||
sorted_files = sorted(files, key=lambda x: x.restore_path, reverse=False)
|
sorted_files = sorted(files, key=lambda x: x.restore_path, reverse=False)
|
||||||
# add the file paths
|
# add the file paths
|
||||||
last_domain = ""
|
last_domain = ""
|
||||||
last_path = ""
|
last_path = ""
|
||||||
exploit_only = True
|
exploit_only = True
|
||||||
for file in sorted_files:
|
for file in sorted_files:
|
||||||
if isinstance(file, AppBundleToRestore):
|
if file.domain == None:
|
||||||
# add bundle id to the manifest
|
|
||||||
apps_list.append(backup.AppBundle(
|
|
||||||
identifier=file.bundle_id,
|
|
||||||
path=file.restore_path,
|
|
||||||
container_content_class=file.container_content_class,
|
|
||||||
version=file.bundle_version
|
|
||||||
))
|
|
||||||
elif file.domain == None:
|
|
||||||
last_domain = concat_exploit_file(file, files_list, last_domain)
|
last_domain = concat_exploit_file(file, files_list, last_domain)
|
||||||
else:
|
else:
|
||||||
last_domain, last_path = concat_regular_file(file, files_list, last_domain, last_path)
|
last_domain, last_path = concat_regular_file(file, files_list, last_domain, last_path)
|
||||||
exploit_only = False
|
exploit_only = False
|
||||||
|
# add the app bundle to the list
|
||||||
|
if last_domain.startswith("AppDomain"):
|
||||||
|
bundle_id = last_domain.removeprefix("AppDomain-")
|
||||||
|
if not bundle_id in active_bundle_ids:
|
||||||
|
if apps == None:
|
||||||
|
apps = InstallationProxyService(lockdown=lockdown_client).get_apps(application_type="Any", calculate_sizes=False)
|
||||||
|
app_info = apps[bundle_id]
|
||||||
|
active_bundle_ids.append(bundle_id)
|
||||||
|
apps_list.append(backup.AppBundle(
|
||||||
|
identifier=bundle_id,
|
||||||
|
path=app_info["Container"],
|
||||||
|
version=app_info["CFBundleVersion"],
|
||||||
|
container_content_class="Data/Application"
|
||||||
|
))
|
||||||
|
|
||||||
# crash the restore to skip the setup (only works for exploit files)
|
# crash the restore to skip the setup (only works for exploit files)
|
||||||
if exploit_only:
|
if exploit_only:
|
||||||
|
|||||||
@@ -325,7 +325,7 @@ class DeviceManager:
|
|||||||
if tweak.enabled and tweak.file_location.value.startswith("/var/mobile/"):
|
if tweak.enabled and tweak.file_location.value.startswith("/var/mobile/"):
|
||||||
uses_domains = True
|
uses_domains = True
|
||||||
elif isinstance(tweak, PosterboardTweak):
|
elif isinstance(tweak, PosterboardTweak):
|
||||||
tweak.apply_tweak(files_to_restore=files_to_restore, lockdown=self.data_singleton.current_device.ld)
|
tweak.apply_tweak(files_to_restore=files_to_restore)
|
||||||
else:
|
else:
|
||||||
if gestalt_plist != None:
|
if gestalt_plist != None:
|
||||||
gestalt_plist = tweak.apply_tweak(gestalt_plist)
|
gestalt_plist = tweak.apply_tweak(gestalt_plist)
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
from .tweak_classes import Tweak
|
from .tweak_classes import Tweak
|
||||||
from Sparserestore.restore import FileToRestore, AppBundleToRestore
|
from Sparserestore.restore import FileToRestore
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
from pymobiledevice3.services.installation_proxy import InstallationProxyService
|
|
||||||
from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider
|
|
||||||
|
|
||||||
class PosterboardTweak(Tweak):
|
class PosterboardTweak(Tweak):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -39,22 +37,12 @@ class PosterboardTweak(Tweak):
|
|||||||
else:
|
else:
|
||||||
self.recursive_add(files_to_restore, os.path.join(curr_path, folder), isAdding=False)
|
self.recursive_add(files_to_restore, os.path.join(curr_path, folder), isAdding=False)
|
||||||
|
|
||||||
def apply_tweak(self, files_to_restore: list[FileToRestore], lockdown: LockdownServiceProvider):
|
def apply_tweak(self, files_to_restore: list[FileToRestore]):
|
||||||
# get the app container and bundle version
|
|
||||||
pbapp = InstallationProxyService(lockdown=lockdown).get_apps(application_type="System", calculate_sizes=False)["com.apple.PosterBoard"]
|
|
||||||
# unzip the file
|
# unzip the file
|
||||||
if self.zip_path == None or not self.enabled:
|
if self.zip_path == None or not self.enabled:
|
||||||
return
|
return
|
||||||
with TemporaryDirectory() as output_dir:
|
with TemporaryDirectory() as output_dir:
|
||||||
with zipfile.ZipFile(self.zip_path, 'r') as zip_ref:
|
with zipfile.ZipFile(self.zip_path, 'r') as zip_ref:
|
||||||
zip_ref.extractall(output_dir)
|
zip_ref.extractall(output_dir)
|
||||||
# first, add the files
|
# add the files
|
||||||
self.recursive_add(files_to_restore, curr_path=output_dir)
|
self.recursive_add(files_to_restore, curr_path=output_dir)
|
||||||
# next, add the app bundle
|
|
||||||
# For UUID: pymobiledevice3 apps list -t System > apps.xml
|
|
||||||
files_to_restore.append(AppBundleToRestore(
|
|
||||||
bundle_id="com.apple.PosterBoard",
|
|
||||||
bundle_version=pbapp["CFBundleInfoDictionaryVersion"],
|
|
||||||
bundle_path=pbapp["Container"],
|
|
||||||
container_content_class="Data/Application"
|
|
||||||
))
|
|
||||||
Reference in New Issue
Block a user