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
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import contextlib
2
3
  import logging
3
4
  import plistlib
4
5
  import socket
@@ -12,8 +13,12 @@ from typing import Any, Optional
12
13
  import IPython
13
14
  from pygments import formatters, highlight, lexers
14
15
 
15
- from pymobiledevice3.exceptions import ConnectionTerminatedError, DeviceNotFoundError, NoDeviceConnectedError, \
16
- PyMobileDevice3Exception
16
+ from pymobiledevice3.exceptions import (
17
+ ConnectionTerminatedError,
18
+ DeviceNotFoundError,
19
+ NoDeviceConnectedError,
20
+ PyMobileDevice3Exception,
21
+ )
17
22
  from pymobiledevice3.osu.os_utils import get_os_utils
18
23
  from pymobiledevice3.usbmux import MuxDevice, select_device
19
24
 
@@ -39,7 +44,7 @@ print(client.recvall(20))
39
44
  """
40
45
 
41
46
 
42
- def build_plist(d: dict, endianity: str = '>', fmt: Enum = plistlib.FMT_XML) -> bytes:
47
+ def build_plist(d: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> bytes:
43
48
  """
44
49
  Convert a dictionary to a plist-formatted byte string prefixed with a length field.
45
50
 
@@ -49,7 +54,7 @@ def build_plist(d: dict, endianity: str = '>', fmt: Enum = plistlib.FMT_XML) ->
49
54
  :return: The plist-formatted byte string.
50
55
  """
51
56
  payload = plistlib.dumps(d, fmt=fmt)
52
- message = struct.pack(endianity + 'L', len(payload))
57
+ message = struct.pack(endianity + "L", len(payload))
53
58
  return message + payload
54
59
 
55
60
 
@@ -65,17 +70,17 @@ def parse_plist(payload: bytes) -> dict:
65
70
  try:
66
71
  return plistlib.loads(payload)
67
72
  except xml.parsers.expat.ExpatError:
68
- payload = bytes([b for b in payload if b >= 0x20 or b in (0x09, 0x0a, 0x0d)])
73
+ payload = bytes([b for b in payload if b >= 0x20 or b in (0x09, 0x0A, 0x0D)])
69
74
  try:
70
75
  return plistlib.loads(payload)
71
- except plistlib.InvalidFileException:
72
- raise PyMobileDevice3Exception(f'parse_plist invalid data: {payload[:100].hex()}')
73
- except plistlib.InvalidFileException:
74
- raise PyMobileDevice3Exception(f'parse_plist invalid data: {payload[:100].hex()}')
76
+ except plistlib.InvalidFileException as e:
77
+ raise PyMobileDevice3Exception(f"parse_plist invalid data: {payload[:100].hex()}") from e
78
+ except plistlib.InvalidFileException as e:
79
+ raise PyMobileDevice3Exception(f"parse_plist invalid data: {payload[:100].hex()}") from e
75
80
 
76
81
 
77
82
  class ServiceConnection:
78
- """ wrapper for tcp-relay connections """
83
+ """wrapper for tcp-relay connections"""
79
84
 
80
85
  def __init__(self, sock: socket.socket, mux_device: MuxDevice = None):
81
86
  """
@@ -100,8 +105,9 @@ class ServiceConnection:
100
105
  self.max_ssl_proto = ssl.TLSVersion.TLSv1_3
101
106
 
102
107
  @staticmethod
103
- def create_using_tcp(hostname: str, port: int, keep_alive: bool = True,
104
- create_connection_timeout: int = DEFAULT_TIMEOUT) -> 'ServiceConnection':
108
+ def create_using_tcp(
109
+ hostname: str, port: int, keep_alive: bool = True, create_connection_timeout: int = DEFAULT_TIMEOUT
110
+ ) -> "ServiceConnection":
105
111
  """
106
112
  Create a ServiceConnection using a TCP connection.
107
113
 
@@ -118,8 +124,9 @@ class ServiceConnection:
118
124
  return ServiceConnection(sock)
119
125
 
120
126
  @staticmethod
121
- def create_using_usbmux(udid: Optional[str], port: int, connection_type: str = None,
122
- usbmux_address: Optional[str] = None) -> 'ServiceConnection':
127
+ def create_using_usbmux(
128
+ udid: Optional[str], port: int, connection_type: Optional[str] = None, usbmux_address: Optional[str] = None
129
+ ) -> "ServiceConnection":
123
130
  """
124
131
  Create a ServiceConnection using a USBMux connection.
125
132
 
@@ -148,18 +155,16 @@ class ServiceConnection:
148
155
  self.socket.setblocking(blocking)
149
156
 
150
157
  def close(self) -> None:
151
- """ Close the connection. """
158
+ """Close the connection."""
152
159
  self.socket.close()
153
160
 
154
161
  async def aio_close(self) -> None:
155
- """ Asynchronously close the connection. """
162
+ """Asynchronously close the connection."""
156
163
  if self.writer is None:
157
164
  return
158
165
  self.writer.close()
159
- try:
166
+ with contextlib.suppress(ssl.SSLError):
160
167
  await self.writer.wait_closed()
161
- except ssl.SSLError:
162
- pass
163
168
  self.writer = None
164
169
  self.reader = None
165
170
 
@@ -172,8 +177,8 @@ class ServiceConnection:
172
177
  """
173
178
  try:
174
179
  return self.socket.recv(length)
175
- except ssl.SSLError:
176
- raise ConnectionAbortedError()
180
+ except ssl.SSLError as e:
181
+ raise ConnectionAbortedError() from e
177
182
 
178
183
  def sendall(self, data: bytes) -> None:
179
184
  """
@@ -187,7 +192,7 @@ class ServiceConnection:
187
192
  except ssl.SSLEOFError as e:
188
193
  raise ConnectionTerminatedError from e
189
194
 
190
- def send_recv_plist(self, data: dict, endianity: str = '>', fmt: Enum = plistlib.FMT_XML) -> Any:
195
+ def send_recv_plist(self, data: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> Any:
191
196
  """
192
197
  Send a plist to the socket and receive a plist response.
193
198
 
@@ -199,7 +204,7 @@ class ServiceConnection:
199
204
  self.send_plist(data, endianity=endianity, fmt=fmt)
200
205
  return self.recv_plist(endianity=endianity)
201
206
 
202
- async def aio_send_recv_plist(self, data: dict, endianity: str = '>', fmt: Enum = plistlib.FMT_XML) -> Any:
207
+ async def aio_send_recv_plist(self, data: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> Any:
203
208
  """
204
209
  Asynchronously send a plist to the socket and receive a plist response.
205
210
 
@@ -219,7 +224,7 @@ class ServiceConnection:
219
224
  :return: The received data.
220
225
  :raises ConnectionAbortedError: If the connection is aborted.
221
226
  """
222
- data = b''
227
+ data = b""
223
228
  while len(data) < size:
224
229
  chunk = self.recv(size - len(data))
225
230
  if chunk is None or len(chunk) == 0:
@@ -227,7 +232,7 @@ class ServiceConnection:
227
232
  data += chunk
228
233
  return data
229
234
 
230
- def recv_prefixed(self, endianity: str = '>') -> bytes:
235
+ def recv_prefixed(self, endianity: str = ">") -> bytes:
231
236
  """
232
237
  Receive a data block prefixed with a length field.
233
238
 
@@ -236,8 +241,8 @@ class ServiceConnection:
236
241
  """
237
242
  size = self.recvall(4)
238
243
  if not size or len(size) != 4:
239
- return b''
240
- size = struct.unpack(endianity + 'L', size)[0]
244
+ return b""
245
+ size = struct.unpack(endianity + "L", size)[0]
241
246
  while True:
242
247
  try:
243
248
  return self.recvall(size)
@@ -254,7 +259,7 @@ class ServiceConnection:
254
259
  """
255
260
  return await self.reader.readexactly(size)
256
261
 
257
- async def aio_recv_prefixed(self, endianity: str = '>') -> bytes:
262
+ async def aio_recv_prefixed(self, endianity: str = ">") -> bytes:
258
263
  """
259
264
  Asynchronously receive a data block prefixed with a length field.
260
265
 
@@ -262,7 +267,7 @@ class ServiceConnection:
262
267
  :return: The received data block.
263
268
  """
264
269
  size = await self.aio_recvall(4)
265
- size = struct.unpack(endianity + 'L', size)[0]
270
+ size = struct.unpack(endianity + "L", size)[0]
266
271
  return await self.aio_recvall(size)
267
272
 
268
273
  def send_prefixed(self, data: bytes) -> None:
@@ -273,11 +278,11 @@ class ServiceConnection:
273
278
  """
274
279
  if isinstance(data, str):
275
280
  data = data.encode()
276
- hdr = struct.pack('>L', len(data))
277
- msg = b''.join([hdr, data])
281
+ hdr = struct.pack(">L", len(data))
282
+ msg = b"".join([hdr, data])
278
283
  return self.sendall(msg)
279
284
 
280
- def recv_plist(self, endianity: str = '>') -> dict:
285
+ def recv_plist(self, endianity: str = ">") -> dict:
281
286
  """
282
287
  Receive a plist from the socket and parse it into a dictionary.
283
288
 
@@ -286,7 +291,7 @@ class ServiceConnection:
286
291
  """
287
292
  return parse_plist(self.recv_prefixed(endianity=endianity))
288
293
 
289
- async def aio_recv_plist(self, endianity: str = '>') -> dict:
294
+ async def aio_recv_plist(self, endianity: str = ">") -> dict:
290
295
  """
291
296
  Asynchronously receive a plist from the socket and parse it into a dictionary.
292
297
 
@@ -295,7 +300,7 @@ class ServiceConnection:
295
300
  """
296
301
  return parse_plist(await self.aio_recv_prefixed(endianity))
297
302
 
298
- def send_plist(self, d: dict, endianity: str = '>', fmt: Enum = plistlib.FMT_XML) -> None:
303
+ def send_plist(self, d: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> None:
299
304
  """
300
305
  Send a dictionary as a plist to the socket.
301
306
 
@@ -314,7 +319,7 @@ class ServiceConnection:
314
319
  self.writer.write(payload)
315
320
  await self.writer.drain()
316
321
 
317
- async def aio_send_plist(self, d: dict, endianity: str = '>', fmt: Enum = plistlib.FMT_XML) -> None:
322
+ async def aio_send_plist(self, d: dict, endianity: str = ">", fmt: Enum = plistlib.FMT_XML) -> None:
318
323
  """
319
324
  Asynchronously send a dictionary as a plist to the socket.
320
325
 
@@ -335,10 +340,10 @@ class ServiceConnection:
335
340
  context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
336
341
  context.minimum_version = self.min_ssl_proto
337
342
  context.maximum_version = self.max_ssl_proto
338
- if ssl.OPENSSL_VERSION.lower().startswith('openssl'):
339
- context.set_ciphers('ALL:!aNULL:!eNULL:@SECLEVEL=0')
343
+ if ssl.OPENSSL_VERSION.lower().startswith("openssl"):
344
+ context.set_ciphers("ALL:!aNULL:!eNULL:@SECLEVEL=0")
340
345
  else:
341
- context.set_ciphers('ALL:!aNULL:!eNULL')
346
+ context.set_ciphers("ALL:!aNULL:!eNULL")
342
347
  context.options |= 0x4 # OPENSSL OP_LEGACY_SERVER_CONNECT (required for legacy iOS devices)
343
348
  context.check_hostname = False
344
349
  context.verify_mode = ssl.CERT_NONE
@@ -362,22 +367,21 @@ class ServiceConnection:
362
367
  :param keyfile: The path to the key file (optional).
363
368
  """
364
369
  self.reader, self.writer = await asyncio.open_connection(
365
- sock=self.socket,
366
- ssl=self.create_ssl_context(certfile, keyfile=keyfile),
367
- server_hostname=''
370
+ sock=self.socket, ssl=self.create_ssl_context(certfile, keyfile=keyfile), server_hostname=""
368
371
  )
369
372
 
370
373
  async def aio_start(self) -> None:
371
- """ Asynchronously start a connection. """
374
+ """Asynchronously start a connection."""
372
375
  self.reader, self.writer = await asyncio.open_connection(sock=self.socket)
373
376
 
374
377
  def shell(self) -> None:
375
- """ Start an interactive shell. """
378
+ """Start an interactive shell."""
376
379
  IPython.embed(
377
- header=highlight(SHELL_USAGE, lexers.PythonLexer(), formatters.Terminal256Formatter(style='native')),
380
+ header=highlight(SHELL_USAGE, lexers.PythonLexer(), formatters.Terminal256Formatter(style="native")),
378
381
  user_ns={
379
- 'client': self,
380
- })
382
+ "client": self,
383
+ },
384
+ )
381
385
 
382
386
  def read(self, size: int) -> bytes:
383
387
  """