pymobiledevice3 5.0.0__py3-none-any.whl → 5.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pymobiledevice3 might be problematic. Click here for more details.

Files changed (143) hide show
  1. misc/plist_sniffer.py +15 -15
  2. misc/remotexpc_sniffer.py +29 -28
  3. pymobiledevice3/__main__.py +128 -102
  4. pymobiledevice3/_version.py +2 -2
  5. pymobiledevice3/bonjour.py +26 -49
  6. pymobiledevice3/ca.py +32 -24
  7. pymobiledevice3/cli/activation.py +7 -7
  8. pymobiledevice3/cli/afc.py +19 -19
  9. pymobiledevice3/cli/amfi.py +4 -4
  10. pymobiledevice3/cli/apps.py +51 -39
  11. pymobiledevice3/cli/backup.py +58 -32
  12. pymobiledevice3/cli/bonjour.py +25 -18
  13. pymobiledevice3/cli/cli_common.py +112 -81
  14. pymobiledevice3/cli/companion_proxy.py +4 -4
  15. pymobiledevice3/cli/completions.py +10 -10
  16. pymobiledevice3/cli/crash.py +37 -31
  17. pymobiledevice3/cli/developer.py +602 -520
  18. pymobiledevice3/cli/diagnostics.py +38 -33
  19. pymobiledevice3/cli/lockdown.py +79 -74
  20. pymobiledevice3/cli/mounter.py +85 -68
  21. pymobiledevice3/cli/notification.py +10 -10
  22. pymobiledevice3/cli/pcap.py +19 -14
  23. pymobiledevice3/cli/power_assertion.py +12 -10
  24. pymobiledevice3/cli/processes.py +10 -10
  25. pymobiledevice3/cli/profile.py +88 -77
  26. pymobiledevice3/cli/provision.py +17 -17
  27. pymobiledevice3/cli/remote.py +186 -110
  28. pymobiledevice3/cli/restore.py +43 -40
  29. pymobiledevice3/cli/springboard.py +30 -28
  30. pymobiledevice3/cli/syslog.py +85 -58
  31. pymobiledevice3/cli/usbmux.py +21 -20
  32. pymobiledevice3/cli/version.py +3 -2
  33. pymobiledevice3/cli/webinspector.py +157 -79
  34. pymobiledevice3/common.py +1 -1
  35. pymobiledevice3/exceptions.py +154 -60
  36. pymobiledevice3/irecv.py +49 -53
  37. pymobiledevice3/irecv_devices.py +1489 -492
  38. pymobiledevice3/lockdown.py +394 -241
  39. pymobiledevice3/lockdown_service_provider.py +5 -7
  40. pymobiledevice3/osu/os_utils.py +18 -9
  41. pymobiledevice3/osu/posix_util.py +28 -15
  42. pymobiledevice3/osu/win_util.py +14 -8
  43. pymobiledevice3/pair_records.py +19 -19
  44. pymobiledevice3/remote/common.py +4 -4
  45. pymobiledevice3/remote/core_device/app_service.py +94 -67
  46. pymobiledevice3/remote/core_device/core_device_service.py +17 -14
  47. pymobiledevice3/remote/core_device/device_info.py +5 -5
  48. pymobiledevice3/remote/core_device/diagnostics_service.py +10 -8
  49. pymobiledevice3/remote/core_device/file_service.py +47 -33
  50. pymobiledevice3/remote/remote_service_discovery.py +53 -35
  51. pymobiledevice3/remote/remotexpc.py +62 -41
  52. pymobiledevice3/remote/tunnel_service.py +371 -293
  53. pymobiledevice3/remote/utils.py +12 -11
  54. pymobiledevice3/remote/xpc_message.py +145 -125
  55. pymobiledevice3/resources/dsc_uuid_map.py +19 -19
  56. pymobiledevice3/resources/firmware_notifications.py +16 -16
  57. pymobiledevice3/restore/asr.py +27 -27
  58. pymobiledevice3/restore/base_restore.py +90 -47
  59. pymobiledevice3/restore/consts.py +87 -66
  60. pymobiledevice3/restore/device.py +11 -11
  61. pymobiledevice3/restore/fdr.py +46 -46
  62. pymobiledevice3/restore/ftab.py +19 -19
  63. pymobiledevice3/restore/img4.py +130 -133
  64. pymobiledevice3/restore/mbn.py +35 -54
  65. pymobiledevice3/restore/recovery.py +125 -135
  66. pymobiledevice3/restore/restore.py +524 -523
  67. pymobiledevice3/restore/restore_options.py +122 -115
  68. pymobiledevice3/restore/restored_client.py +25 -22
  69. pymobiledevice3/restore/tss.py +378 -270
  70. pymobiledevice3/service_connection.py +50 -46
  71. pymobiledevice3/services/accessibilityaudit.py +136 -126
  72. pymobiledevice3/services/afc.py +350 -291
  73. pymobiledevice3/services/amfi.py +21 -18
  74. pymobiledevice3/services/companion.py +23 -19
  75. pymobiledevice3/services/crash_reports.py +60 -46
  76. pymobiledevice3/services/debugserver_applist.py +3 -3
  77. pymobiledevice3/services/device_arbitration.py +8 -8
  78. pymobiledevice3/services/device_link.py +55 -47
  79. pymobiledevice3/services/diagnostics.py +971 -968
  80. pymobiledevice3/services/dtfetchsymbols.py +8 -8
  81. pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +4 -4
  82. pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +4 -4
  83. pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +85 -74
  84. pymobiledevice3/services/dvt/instruments/application_listing.py +2 -3
  85. pymobiledevice3/services/dvt/instruments/condition_inducer.py +7 -6
  86. pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +466 -384
  87. pymobiledevice3/services/dvt/instruments/device_info.py +11 -11
  88. pymobiledevice3/services/dvt/instruments/energy_monitor.py +1 -1
  89. pymobiledevice3/services/dvt/instruments/graphics.py +1 -1
  90. pymobiledevice3/services/dvt/instruments/location_simulation.py +1 -1
  91. pymobiledevice3/services/dvt/instruments/location_simulation_base.py +10 -10
  92. pymobiledevice3/services/dvt/instruments/network_monitor.py +17 -17
  93. pymobiledevice3/services/dvt/instruments/notifications.py +1 -1
  94. pymobiledevice3/services/dvt/instruments/process_control.py +25 -10
  95. pymobiledevice3/services/dvt/instruments/screenshot.py +2 -2
  96. pymobiledevice3/services/dvt/instruments/sysmontap.py +15 -15
  97. pymobiledevice3/services/dvt/testmanaged/xcuitest.py +40 -50
  98. pymobiledevice3/services/file_relay.py +10 -10
  99. pymobiledevice3/services/heartbeat.py +8 -7
  100. pymobiledevice3/services/house_arrest.py +12 -15
  101. pymobiledevice3/services/installation_proxy.py +119 -100
  102. pymobiledevice3/services/lockdown_service.py +12 -5
  103. pymobiledevice3/services/misagent.py +22 -19
  104. pymobiledevice3/services/mobile_activation.py +84 -72
  105. pymobiledevice3/services/mobile_config.py +330 -301
  106. pymobiledevice3/services/mobile_image_mounter.py +137 -116
  107. pymobiledevice3/services/mobilebackup2.py +188 -150
  108. pymobiledevice3/services/notification_proxy.py +11 -11
  109. pymobiledevice3/services/os_trace.py +69 -51
  110. pymobiledevice3/services/pcapd.py +306 -306
  111. pymobiledevice3/services/power_assertion.py +10 -9
  112. pymobiledevice3/services/preboard.py +4 -4
  113. pymobiledevice3/services/remote_fetch_symbols.py +16 -14
  114. pymobiledevice3/services/remote_server.py +176 -146
  115. pymobiledevice3/services/restore_service.py +16 -16
  116. pymobiledevice3/services/screenshot.py +13 -10
  117. pymobiledevice3/services/simulate_location.py +7 -7
  118. pymobiledevice3/services/springboard.py +15 -15
  119. pymobiledevice3/services/syslog.py +5 -5
  120. pymobiledevice3/services/web_protocol/alert.py +3 -3
  121. pymobiledevice3/services/web_protocol/automation_session.py +180 -176
  122. pymobiledevice3/services/web_protocol/cdp_screencast.py +44 -36
  123. pymobiledevice3/services/web_protocol/cdp_server.py +19 -19
  124. pymobiledevice3/services/web_protocol/cdp_target.py +411 -373
  125. pymobiledevice3/services/web_protocol/driver.py +47 -45
  126. pymobiledevice3/services/web_protocol/element.py +74 -63
  127. pymobiledevice3/services/web_protocol/inspector_session.py +106 -102
  128. pymobiledevice3/services/web_protocol/selenium_api.py +2 -2
  129. pymobiledevice3/services/web_protocol/session_protocol.py +15 -10
  130. pymobiledevice3/services/web_protocol/switch_to.py +11 -12
  131. pymobiledevice3/services/webinspector.py +127 -116
  132. pymobiledevice3/tcp_forwarder.py +35 -22
  133. pymobiledevice3/tunneld/api.py +20 -15
  134. pymobiledevice3/tunneld/server.py +212 -133
  135. pymobiledevice3/usbmux.py +183 -138
  136. pymobiledevice3/utils.py +14 -11
  137. {pymobiledevice3-5.0.0.dist-info → pymobiledevice3-5.0.2.dist-info}/METADATA +1 -1
  138. pymobiledevice3-5.0.2.dist-info/RECORD +173 -0
  139. pymobiledevice3-5.0.0.dist-info/RECORD +0 -173
  140. {pymobiledevice3-5.0.0.dist-info → pymobiledevice3-5.0.2.dist-info}/WHEEL +0 -0
  141. {pymobiledevice3-5.0.0.dist-info → pymobiledevice3-5.0.2.dist-info}/entry_points.txt +0 -0
  142. {pymobiledevice3-5.0.0.dist-info → pymobiledevice3-5.0.2.dist-info}/licenses/LICENSE +0 -0
  143. {pymobiledevice3-5.0.0.dist-info → pymobiledevice3-5.0.2.dist-info}/top_level.txt +0 -0
@@ -29,28 +29,28 @@ class ASRClient:
29
29
 
30
30
  def __init__(self, udid: str) -> None:
31
31
  self._udid: str = udid
32
- self.logger = logging.getLogger(f'{asyncio.current_task().get_name()}-{__name__}')
32
+ self.logger = logging.getLogger(f"{asyncio.current_task().get_name()}-{__name__}")
33
33
  self.service: typing.Optional[ServiceConnection] = None
34
34
  self.checksum_chunks: bool = False
35
35
 
36
36
  async def connect(self, port: int = DEFAULT_ASR_SYNC_PORT) -> None:
37
- self.service = ServiceConnection.create_using_usbmux(self._udid, port, connection_type='USB')
37
+ self.service = ServiceConnection.create_using_usbmux(self._udid, port, connection_type="USB")
38
38
  await self.service.aio_start()
39
39
 
40
40
  # receive Initiate command message
41
41
  data = await self.recv_plist()
42
- self.logger.debug(f'got command: {data}')
42
+ self.logger.debug(f"got command: {data}")
43
43
 
44
- command = data.get('Command')
45
- if command != 'Initiate':
46
- raise PyMobileDevice3Exception(f'invalid command received: {command}')
44
+ command = data.get("Command")
45
+ if command != "Initiate":
46
+ raise PyMobileDevice3Exception(f"invalid command received: {command}")
47
47
 
48
- self.checksum_chunks = data.get('Checksum Chunks', False)
49
- self.logger.debug(f'Checksum Chunks: {self.checksum_chunks}')
48
+ self.checksum_chunks = data.get("Checksum Chunks", False)
49
+ self.logger.debug(f"Checksum Chunks: {self.checksum_chunks}")
50
50
 
51
51
  async def recv_plist(self) -> dict:
52
- buf = b''
53
- while not buf.endswith(b'</plist>\n'):
52
+ buf = b""
53
+ while not buf.endswith(b"</plist>\n"):
54
54
  buf += await self.service.aio_recvall(1)
55
55
  return plistlib.loads(buf)
56
56
 
@@ -62,8 +62,8 @@ class ASRClient:
62
62
  await self.service.aio_sendall(buf)
63
63
 
64
64
  async def handle_oob_data_request(self, packet: dict, filesystem: typing.IO):
65
- oob_length = packet['OOB Length']
66
- oob_offset = packet['OOB Offset']
65
+ oob_length = packet["OOB Length"]
66
+ oob_offset = packet["OOB Offset"]
67
67
  filesystem.seek(oob_offset, os.SEEK_SET)
68
68
 
69
69
  oob_data = filesystem.read(oob_length)
@@ -77,36 +77,36 @@ class ASRClient:
77
77
  filesystem.seek(0, os.SEEK_SET)
78
78
 
79
79
  payload_info = {
80
- 'Port': 1,
81
- 'Size': length,
80
+ "Port": 1,
81
+ "Size": length,
82
82
  }
83
83
 
84
- packet_info = dict()
84
+ packet_info = {}
85
85
  if self.checksum_chunks:
86
- packet_info['Checksum Chunk Size'] = ASR_CHECKSUM_CHUNK_SIZE
86
+ packet_info["Checksum Chunk Size"] = ASR_CHECKSUM_CHUNK_SIZE
87
87
 
88
- packet_info['FEC Slice Stride'] = ASR_FEC_SLICE_STRIDE
89
- packet_info['Packet Payload Size'] = ASR_PAYLOAD_PACKET_SIZE
90
- packet_info['Packets Per FEC'] = ASR_PACKETS_PER_FEC
91
- packet_info['Payload'] = payload_info
92
- packet_info['Stream ID'] = ASR_STREAM_ID
93
- packet_info['Version'] = ASR_VERSION
88
+ packet_info["FEC Slice Stride"] = ASR_FEC_SLICE_STRIDE
89
+ packet_info["Packet Payload Size"] = ASR_PAYLOAD_PACKET_SIZE
90
+ packet_info["Packets Per FEC"] = ASR_PACKETS_PER_FEC
91
+ packet_info["Payload"] = payload_info
92
+ packet_info["Stream ID"] = ASR_STREAM_ID
93
+ packet_info["Version"] = ASR_VERSION
94
94
 
95
95
  await self.send_plist(packet_info)
96
96
 
97
97
  while True:
98
98
  packet = await self.recv_plist()
99
- self.logger.debug(f'perform_validation: {packet}')
100
- command = packet['Command']
99
+ self.logger.debug(f"perform_validation: {packet}")
100
+ command = packet["Command"]
101
101
 
102
- if command == 'Payload':
102
+ if command == "Payload":
103
103
  break
104
104
 
105
- elif command == 'OOBData':
105
+ elif command == "OOBData":
106
106
  await self.handle_oob_data_request(packet, filesystem)
107
107
 
108
108
  else:
109
- raise PyMobileDevice3Exception(f'unknown packet: {packet}')
109
+ raise PyMobileDevice3Exception(f"unknown packet: {packet}")
110
110
 
111
111
  async def send_payload(self, filesystem: typing.IO) -> None:
112
112
  filesystem.seek(0, os.SEEK_END)
@@ -12,29 +12,30 @@ from pymobiledevice3.restore.device import Device
12
12
  from pymobiledevice3.restore.img4 import stitch_component
13
13
  from pymobiledevice3.restore.tss import TSSResponse
14
14
 
15
- RESTORE_VARIANT_ERASE_INSTALL = 'Erase Install (IPSW)'
16
- RESTORE_VARIANT_UPGRADE_INSTALL = 'Upgrade Install (IPSW)'
17
- RESTORE_VARIANT_MACOS_RECOVERY_OS = 'macOS Customer'
15
+ RESTORE_VARIANT_ERASE_INSTALL = "Erase Install (IPSW)"
16
+ RESTORE_VARIANT_UPGRADE_INSTALL = "Upgrade Install (IPSW)"
17
+ RESTORE_VARIANT_MACOS_RECOVERY_OS = "macOS Customer"
18
18
 
19
19
 
20
20
  class Behavior(Enum):
21
- Update = 'Update'
22
- Erase = 'Erase'
21
+ Update = "Update"
22
+ Erase = "Erase"
23
23
 
24
24
 
25
25
  class BaseRestore:
26
- def __init__(self, ipsw: ZipFile, device: Device, tss: Optional[dict] = None,
27
- behavior: Behavior = Behavior.Update) -> None:
26
+ def __init__(
27
+ self, ipsw: ZipFile, device: Device, tss: Optional[dict] = None, behavior: Behavior = Behavior.Update
28
+ ) -> None:
28
29
  self.ipsw = IPSW(ipsw)
29
30
  self.device = device
30
31
  self.tss = TSSResponse(tss) if tss is not None else None
31
32
 
32
33
  if not self.device.is_image4_supported:
33
- raise NotImplementedError('is_image4_supported is False')
34
+ raise NotImplementedError("is_image4_supported is False")
34
35
 
35
- self.logger.info(f'connected device: {self.device}')
36
+ self.logger.info(f"connected device: {self.device}")
36
37
 
37
- self.logger.debug('scanning BuildManifest.plist for the correct BuildIdentity')
38
+ self.logger.debug("scanning BuildManifest.plist for the correct BuildIdentity")
38
39
 
39
40
  variant = {
40
41
  Behavior.Update: RESTORE_VARIANT_UPGRADE_INSTALL,
@@ -42,68 +43,110 @@ class BaseRestore:
42
43
  }[behavior]
43
44
 
44
45
  try:
45
- self.build_identity = self.ipsw.build_manifest.get_build_identity(self.device.hardware_model,
46
- restore_behavior=behavior.value,
47
- variant=variant)
46
+ self.build_identity = self.ipsw.build_manifest.get_build_identity(
47
+ self.device.hardware_model, restore_behavior=behavior.value, variant=variant
48
+ )
48
49
  except NoSuchBuildIdentityError:
49
50
  if behavior == Behavior.Update:
50
- self.build_identity = self.ipsw.build_manifest.get_build_identity(self.device.hardware_model,
51
- restore_behavior=behavior.value)
51
+ self.build_identity = self.ipsw.build_manifest.get_build_identity(
52
+ self.device.hardware_model, restore_behavior=behavior.value
53
+ )
52
54
  else:
53
55
  raise
54
56
 
55
57
  self.macos_variant = None
56
58
  try:
57
59
  self.macos_variant = self.ipsw.build_manifest.get_build_identity(
58
- self.device.hardware_model,
59
- variant=RESTORE_VARIANT_MACOS_RECOVERY_OS)
60
- self.logger.info('Performing macOS restore')
60
+ self.device.hardware_model, variant=RESTORE_VARIANT_MACOS_RECOVERY_OS
61
+ )
62
+ self.logger.info("Performing macOS restore")
61
63
  except NoSuchBuildIdentityError:
62
64
  pass
63
65
 
64
- build_info = self.build_identity.get('Info')
66
+ build_info = self.build_identity.get("Info")
65
67
  if build_info is None:
66
68
  raise PyMobileDevice3Exception('build identity does not contain an "Info" element')
67
69
 
68
- device_class = build_info.get('DeviceClass')
70
+ device_class = build_info.get("DeviceClass")
69
71
  if device_class is None:
70
72
  raise PyMobileDevice3Exception('build identity does not contain an "DeviceClass" element')
71
73
 
72
74
  @property
73
75
  def logger(self) -> logging.Logger:
74
- return logging.getLogger(f'{asyncio.current_task().get_name()}-{self.__class__.__module__}')
75
-
76
- def get_personalized_data(self, component_name: str, data: Optional[bytes] = None,
77
- tss: Optional[TSSResponse] = None, path: Optional[str] = None) -> bytes:
78
- return stitch_component(component_name,
79
- self.build_identity.get_component(component_name, tss=tss, data=data, path=path).data,
80
- tss,
81
- self.build_identity,
82
- self.device.ap_parameters)
76
+ return logging.getLogger(f"{asyncio.current_task().get_name()}-{self.__class__.__module__}")
77
+
78
+ def get_personalized_data(
79
+ self,
80
+ component_name: str,
81
+ data: Optional[bytes] = None,
82
+ tss: Optional[TSSResponse] = None,
83
+ path: Optional[str] = None,
84
+ ) -> bytes:
85
+ return stitch_component(
86
+ component_name,
87
+ self.build_identity.get_component(component_name, tss=tss, data=data, path=path).data,
88
+ tss,
89
+ self.build_identity,
90
+ self.device.ap_parameters,
91
+ )
83
92
 
84
93
  def populate_tss_request_from_manifest(self, parameters: dict, additional_keys: Optional[list[str]] = None) -> None:
85
- """ equivalent to idevicerestore:tss_parameters_add_from_manifest """
86
- key_list = ['ApBoardID', 'ApChipID']
94
+ """equivalent to idevicerestore:tss_parameters_add_from_manifest"""
95
+ key_list = ["ApBoardID", "ApChipID"]
87
96
  if additional_keys is None:
88
- key_list += ['UniqueBuildID', 'Ap,OSLongVersion', 'Ap,OSReleaseType', 'Ap,ProductType', 'Ap,SDKPlatform',
89
- 'Ap,SikaFuse', 'Ap,Target', 'Ap,TargetType', 'ApBoardID', 'ApChipID',
90
- 'ApSecurityDomain', 'BMU,BoardID', 'BMU,ChipID', 'BbChipID', 'BbProvisioningManifestKeyHash',
91
- 'BbActivationManifestKeyHash', 'BbCalibrationManifestKeyHash', 'Ap,ProductMarketingVersion',
92
- 'BbFactoryActivationManifestKeyHash', 'BbFDRSecurityKeyHash', 'BbSkeyId', 'SE,ChipID',
93
- 'Savage,ChipID', 'Savage,PatchEpoch', 'Yonkers,BoardID', 'Yonkers,ChipID',
94
- 'Yonkers,PatchEpoch', 'Rap,BoardID', 'Rap,ChipID', 'Rap,SecurityDomain', 'Baobab,BoardID',
95
- 'Baobab,ChipID', 'Baobab,ManifestEpoch', 'Baobab,SecurityDomain', 'eUICC,ChipID',
96
- 'PearlCertificationRootPub', 'Timer,BoardID,1', 'Timer,BoardID,2', 'Timer,ChipID,1',
97
- 'Timer,ChipID,2', 'Timer,SecurityDomain,1', 'Timer,SecurityDomain,2', 'Manifest',
98
- 'NeRDEpoch',
99
- ]
97
+ key_list += [
98
+ "UniqueBuildID",
99
+ "Ap,OSLongVersion",
100
+ "Ap,OSReleaseType",
101
+ "Ap,ProductType",
102
+ "Ap,SDKPlatform",
103
+ "Ap,SikaFuse",
104
+ "Ap,Target",
105
+ "Ap,TargetType",
106
+ "ApBoardID",
107
+ "ApChipID",
108
+ "ApSecurityDomain",
109
+ "BMU,BoardID",
110
+ "BMU,ChipID",
111
+ "BbChipID",
112
+ "BbProvisioningManifestKeyHash",
113
+ "BbActivationManifestKeyHash",
114
+ "BbCalibrationManifestKeyHash",
115
+ "Ap,ProductMarketingVersion",
116
+ "BbFactoryActivationManifestKeyHash",
117
+ "BbFDRSecurityKeyHash",
118
+ "BbSkeyId",
119
+ "SE,ChipID",
120
+ "Savage,ChipID",
121
+ "Savage,PatchEpoch",
122
+ "Yonkers,BoardID",
123
+ "Yonkers,ChipID",
124
+ "Yonkers,PatchEpoch",
125
+ "Rap,BoardID",
126
+ "Rap,ChipID",
127
+ "Rap,SecurityDomain",
128
+ "Baobab,BoardID",
129
+ "Baobab,ChipID",
130
+ "Baobab,ManifestEpoch",
131
+ "Baobab,SecurityDomain",
132
+ "eUICC,ChipID",
133
+ "PearlCertificationRootPub",
134
+ "Timer,BoardID,1",
135
+ "Timer,BoardID,2",
136
+ "Timer,ChipID,1",
137
+ "Timer,ChipID,2",
138
+ "Timer,SecurityDomain,1",
139
+ "Timer,SecurityDomain,2",
140
+ "Manifest",
141
+ "NeRDEpoch",
142
+ ]
100
143
  else:
101
144
  key_list += additional_keys
102
145
 
103
146
  for k in key_list:
104
147
  try:
105
148
  v = self.build_identity[k]
106
- if isinstance(v, str) and v.startswith('0x'):
149
+ if isinstance(v, str) and v.startswith("0x"):
107
150
  v = int(v, 16)
108
151
  parameters[k] = v
109
152
  except KeyError:
@@ -111,9 +154,9 @@ class BaseRestore:
111
154
 
112
155
  if additional_keys is None:
113
156
  # special treat for RequiresUIDMode
114
- info = self.build_identity.get('Info')
157
+ info = self.build_identity.get("Info")
115
158
  if info is None:
116
159
  return
117
- requires_uid_mode = info.get('RequiresUIDMode')
160
+ requires_uid_mode = info.get("RequiresUIDMode")
118
161
  if requires_uid_mode is not None:
119
- parameters['RequiresUIDMode'] = requires_uid_mode
162
+ parameters["RequiresUIDMode"] = requires_uid_mode
@@ -1,70 +1,91 @@
1
- lpol_file = bytes([0x30, 0x14, 0x16, 0x04, 0x49, 0x4d, 0x34, 0x50,
2
- 0x16, 0x04, 0x6c, 0x70, 0x6f, 0x6c, 0x16, 0x03,
3
- 0x31, 0x2e, 0x30, 0x04, 0x01, 0x00])
1
+ lpol_file = bytes([
2
+ 0x30,
3
+ 0x14,
4
+ 0x16,
5
+ 0x04,
6
+ 0x49,
7
+ 0x4D,
8
+ 0x34,
9
+ 0x50,
10
+ 0x16,
11
+ 0x04,
12
+ 0x6C,
13
+ 0x70,
14
+ 0x6F,
15
+ 0x6C,
16
+ 0x16,
17
+ 0x03,
18
+ 0x31,
19
+ 0x2E,
20
+ 0x30,
21
+ 0x04,
22
+ 0x01,
23
+ 0x00,
24
+ ])
4
25
 
5
26
  # extracted from ac2
6
27
  PROGRESS_BAR_OPERATIONS = {
7
- 11: 'CREATE_PARTITION_MAP',
8
- 12: 'CREATE_FILESYSTEM',
9
- 13: 'RESTORE_IMAGE',
10
- 14: 'VERIFY_RESTORE',
11
- 15: 'CHECK_FILESYSTEMS',
12
- 16: 'MOUNT_FILESYSTEMS',
13
- 17: 'FIXUP_VAR',
14
- 18: 'FLASH_FIRMWARE',
15
- 19: 'UPDATE_BASEBAND',
16
- 20: 'SET_BOOT_STAGE',
17
- 21: 'REBOOT_DEVICE',
18
- 22: 'SHUTDOWN_DEVICE',
19
- 23: 'TURN_ON_ACCESSORY_POWER',
20
- 24: 'CLEAR_BOOTARGS',
21
- 25: 'MODIFY_BOOTARGS',
22
- 26: 'INSTALL_ROOT',
23
- 27: 'INSTALL_KERNELCACHE',
24
- 28: 'WAIT_FOR_NAND',
25
- 29: 'UNMOUNT_FILESYSTEMS',
26
- 30: 'SET_DATETIME',
27
- 31: 'EXEC_IBOOT',
28
- 32: 'FINALIZE_NAND_EPOCH_UPDATE',
29
- 33: 'CHECK_INAPPR_BOOT_PARTITIONS',
30
- 34: 'CREATE_FACTORY_RESTORE_MARKER',
31
- 35: 'LOAD_FIRMWARE',
32
- 36: 'REQUESTING_FUD_DATA',
33
- 37: 'REMOVING_ACTIVATION_RECORD',
34
- 38: 'CHECK_BATTERY_VOLTAGE',
35
- 39: 'WAIT_BATTERY_CHARGE',
36
- 40: 'CLOSE_MODEM_TICKETS',
37
- 41: 'MIGRATE_DATA',
38
- 42: 'WIPE_STORAGE_DEVICE',
39
- 43: 'SEND_APPLE_LOGO',
40
- 44: 'CHECK_LOGS',
41
- 46: 'CLEAR_NVRAM',
42
- 47: 'UPDATE_GAS_GAUGE',
43
- 48: 'PREPARE_BASEBAND_UPDATE',
44
- 49: 'BOOT_BASEBAND',
45
- 50: 'CREATE_SYSTEM_KEYBAG',
46
- 51: 'UPDATE_IR_MCU_FIRMWARE',
47
- 52: 'RESIZE_SYSTEM_PARTITION',
48
- 53: 'COLLECTING_UPDATER_OUTPUT',
49
- 54: 'PAIR_STOCKHOLM',
50
- 55: 'UPDATE_STOCKHOLM',
51
- 56: 'UPDATE_SWDHID',
52
- 57: 'CERTIFY_SEP',
53
- 58: 'UPDATE_NAND_FIRMWARE',
54
- 59: 'UPDATE_SE_FIRMWARE',
55
- 60: 'UPDATE_SAVAGE',
56
- 61: 'INSTALLING_DEVICETREE',
57
- 62: 'CERTIFY_SAVAGE',
58
- 63: 'SUBMITTING_PROVINFO',
59
- 64: 'CERTIFY_YONKERS',
60
- 65: 'UPDATE_ROSE',
61
- 66: 'UPDATE_VERIDIAN',
62
- 67: 'CREATING_PROTECTED_VOLUME',
63
- 68: 'RESIZING_MAIN_FS_PARTITION',
64
- 69: 'CREATING_RECOVERY_OS_VOLUME',
65
- 70: 'INSTALLING_RECOVERY_OS_FILES',
66
- 71: 'INSTALLING_RECOVERY_OS_IMAGE',
67
- 74: 'REQUESTING_EAN_DATA',
68
- 77: 'SEALING_SYSTEM_VOLUME',
69
- 81: 'UPDATING_APPLETCON',
28
+ 11: "CREATE_PARTITION_MAP",
29
+ 12: "CREATE_FILESYSTEM",
30
+ 13: "RESTORE_IMAGE",
31
+ 14: "VERIFY_RESTORE",
32
+ 15: "CHECK_FILESYSTEMS",
33
+ 16: "MOUNT_FILESYSTEMS",
34
+ 17: "FIXUP_VAR",
35
+ 18: "FLASH_FIRMWARE",
36
+ 19: "UPDATE_BASEBAND",
37
+ 20: "SET_BOOT_STAGE",
38
+ 21: "REBOOT_DEVICE",
39
+ 22: "SHUTDOWN_DEVICE",
40
+ 23: "TURN_ON_ACCESSORY_POWER",
41
+ 24: "CLEAR_BOOTARGS",
42
+ 25: "MODIFY_BOOTARGS",
43
+ 26: "INSTALL_ROOT",
44
+ 27: "INSTALL_KERNELCACHE",
45
+ 28: "WAIT_FOR_NAND",
46
+ 29: "UNMOUNT_FILESYSTEMS",
47
+ 30: "SET_DATETIME",
48
+ 31: "EXEC_IBOOT",
49
+ 32: "FINALIZE_NAND_EPOCH_UPDATE",
50
+ 33: "CHECK_INAPPR_BOOT_PARTITIONS",
51
+ 34: "CREATE_FACTORY_RESTORE_MARKER",
52
+ 35: "LOAD_FIRMWARE",
53
+ 36: "REQUESTING_FUD_DATA",
54
+ 37: "REMOVING_ACTIVATION_RECORD",
55
+ 38: "CHECK_BATTERY_VOLTAGE",
56
+ 39: "WAIT_BATTERY_CHARGE",
57
+ 40: "CLOSE_MODEM_TICKETS",
58
+ 41: "MIGRATE_DATA",
59
+ 42: "WIPE_STORAGE_DEVICE",
60
+ 43: "SEND_APPLE_LOGO",
61
+ 44: "CHECK_LOGS",
62
+ 46: "CLEAR_NVRAM",
63
+ 47: "UPDATE_GAS_GAUGE",
64
+ 48: "PREPARE_BASEBAND_UPDATE",
65
+ 49: "BOOT_BASEBAND",
66
+ 50: "CREATE_SYSTEM_KEYBAG",
67
+ 51: "UPDATE_IR_MCU_FIRMWARE",
68
+ 52: "RESIZE_SYSTEM_PARTITION",
69
+ 53: "COLLECTING_UPDATER_OUTPUT",
70
+ 54: "PAIR_STOCKHOLM",
71
+ 55: "UPDATE_STOCKHOLM",
72
+ 56: "UPDATE_SWDHID",
73
+ 57: "CERTIFY_SEP",
74
+ 58: "UPDATE_NAND_FIRMWARE",
75
+ 59: "UPDATE_SE_FIRMWARE",
76
+ 60: "UPDATE_SAVAGE",
77
+ 61: "INSTALLING_DEVICETREE",
78
+ 62: "CERTIFY_SAVAGE",
79
+ 63: "SUBMITTING_PROVINFO",
80
+ 64: "CERTIFY_YONKERS",
81
+ 65: "UPDATE_ROSE",
82
+ 66: "UPDATE_VERIDIAN",
83
+ 67: "CREATING_PROTECTED_VOLUME",
84
+ 68: "RESIZING_MAIN_FS_PARTITION",
85
+ 69: "CREATING_RECOVERY_OS_VOLUME",
86
+ 70: "INSTALLING_RECOVERY_OS_FILES",
87
+ 71: "INSTALLING_RECOVERY_OS_IMAGE",
88
+ 74: "REQUESTING_EAN_DATA",
89
+ 77: "SEALING_SYSTEM_VOLUME",
90
+ 81: "UPDATING_APPLETCON",
70
91
  }
@@ -14,10 +14,10 @@ class Device:
14
14
 
15
15
  def __repr__(self) -> str:
16
16
  return (
17
- f'<{self.__class__.__name__} '
18
- f'ecid: {self.ecid} '
19
- f'hardware_model: {self.hardware_model} '
20
- f'image4-support: {self.is_image4_supported}>'
17
+ f"<{self.__class__.__name__} "
18
+ f"ecid: {self.ecid} "
19
+ f"hardware_model: {self.hardware_model} "
20
+ f"image4-support: {self.is_image4_supported}>"
21
21
  )
22
22
 
23
23
  @cached_property
@@ -29,20 +29,20 @@ class Device:
29
29
  @cached_property
30
30
  def hardware_model(self):
31
31
  if self.lockdown:
32
- return self.lockdown.all_values['HardwareModel'].lower()
32
+ return self.lockdown.all_values["HardwareModel"].lower()
33
33
  return self.irecv.hardware_model
34
34
 
35
35
  @cached_property
36
36
  def is_image4_supported(self):
37
37
  if self.lockdown:
38
- return self.lockdown.get_value(key='Image4Supported')
38
+ return self.lockdown.get_value(key="Image4Supported")
39
39
  return self.irecv.is_image4_supported
40
40
 
41
41
  @cached_property
42
42
  def ap_parameters(self) -> dict:
43
43
  if self.lockdown:
44
44
  try:
45
- return self.lockdown.get_value(key='ApParameters')
45
+ return self.lockdown.get_value(key="ApParameters")
46
46
  except MissingValueError:
47
47
  pass
48
48
  return {}
@@ -50,19 +50,19 @@ class Device:
50
50
  @cached_property
51
51
  def ap_nonce(self):
52
52
  if self.lockdown:
53
- ap_nonce_from_ap_parameters = self.ap_parameters.get('ApNonce')
53
+ ap_nonce_from_ap_parameters = self.ap_parameters.get("ApNonce")
54
54
  if ap_nonce_from_ap_parameters:
55
55
  return ap_nonce_from_ap_parameters
56
- return self.lockdown.get_value(key='ApNonce')
56
+ return self.lockdown.get_value(key="ApNonce")
57
57
  return self.irecv.ap_nonce
58
58
 
59
59
  @cached_property
60
60
  def sep_nonce(self):
61
61
  if self.lockdown:
62
- sep_nonce_from_ap_parameters = self.ap_parameters.get('SepNonce')
62
+ sep_nonce_from_ap_parameters = self.ap_parameters.get("SepNonce")
63
63
  if sep_nonce_from_ap_parameters:
64
64
  return sep_nonce_from_ap_parameters
65
- return self.lockdown.get_value(key='SEPNonce')
65
+ return self.lockdown.get_value(key="SEPNonce")
66
66
  return self.irecv.sep_nonce
67
67
 
68
68
  @cached_property