From e78aebc8492cc6883445c1169d44f2ee430e7963 Mon Sep 17 00:00:00 2001 From: doronz Date: Sun, 16 Jul 2023 11:36:21 +0300 Subject: [PATCH] wip --- pymobiledevice3/cli/cli_common.py | 18 +++- pymobiledevice3/cli/remote.py | 85 +++++++++++++++++-- pymobiledevice3/lockdown.py | 21 ++--- pymobiledevice3/lockdown_service_provider.py | 24 ++++++ .../remote/remote_service_discovery.py | 40 +++++++-- pymobiledevice3/remote/remotexpc.py | 3 +- pymobiledevice3/remote/xpc_message.py | 5 +- pymobiledevice3/services/base_service.py | 10 +-- .../services/dvt/dvt_secure_socket_proxy.py | 10 ++- .../instruments/core_profile_session_tap.py | 11 ++- .../services/dvt/instruments/device_info.py | 6 +- pymobiledevice3/services/os_trace.py | 10 ++- pymobiledevice3/services/remote_server.py | 5 +- pymobiledevice3/services/syslog.py | 9 +- 14 files changed, 209 insertions(+), 48 deletions(-) create mode 100644 pymobiledevice3/lockdown_service_provider.py diff --git a/pymobiledevice3/cli/cli_common.py b/pymobiledevice3/cli/cli_common.py index 7418d1870..37cb9b3c2 100644 --- a/pymobiledevice3/cli/cli_common.py +++ b/pymobiledevice3/cli/cli_common.py @@ -3,7 +3,7 @@ import logging import os import uuid -from typing import List, Optional +from typing import List, Optional, Tuple import click import coloredlogs @@ -14,6 +14,7 @@ from pymobiledevice3.exceptions import NoDeviceSelectedError from pymobiledevice3.lockdown import LockdownClient, create_using_usbmux +from pymobiledevice3.remote.remote_service_discovery import RemoteServiceDiscoveryService from pymobiledevice3.usbmux import select_devices_by_connection_type @@ -69,18 +70,29 @@ class Command(click.Command): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.params[:0] = [ + click.Option(('lockdown', '--rsd'), type=(str, int), callback=self.rsd, + help='RSD hostname and port number'), click.Option(('lockdown', '--udid'), envvar=UDID_ENV_VAR, callback=self.udid, help=f'Device unique identifier. You may pass {UDID_ENV_VAR} environment variable to pass this' f' option as well'), click.Option(('verbosity', '-v', '--verbose'), count=True, callback=set_verbosity, expose_value=False), ] + self.service_provider = None - @staticmethod - def udid(ctx, param: str, value: str) -> Optional[LockdownClient]: + def rsd(self, ctx, param: str, value: Optional[Tuple[str, int]]) -> Optional[RemoteServiceDiscoveryService]: + if value is not None: + with RemoteServiceDiscoveryService(value) as rsd: + self.service_provider = rsd + return self.service_provider + + def udid(self, ctx, param: str, value: str) -> Optional[LockdownClient]: if '_PYMOBILEDEVICE3_COMPLETE' in os.environ: # prevent lockdown connection establishment when in autocomplete mode return + if self.service_provider is not None: + return self.service_provider + if value is not None: return create_using_usbmux(serial=value) diff --git a/pymobiledevice3/cli/remote.py b/pymobiledevice3/cli/remote.py index fbc31d5ef..e66b63048 100644 --- a/pymobiledevice3/cli/remote.py +++ b/pymobiledevice3/cli/remote.py @@ -1,21 +1,23 @@ import asyncio import logging import os -from typing import Optional +from typing import Optional, Tuple import click from cryptography.hazmat.primitives.asymmetric import rsa from pymobiledevice3.cli.cli_common import UDID_ENV_VAR, print_json, prompt_device_list, set_verbosity from pymobiledevice3.exceptions import NoDeviceConnectedError +from pymobiledevice3.lockdown import create_using_remote from pymobiledevice3.remote.core_device_tunnel_service import create_core_device_tunnel_service from pymobiledevice3.remote.remote_service_discovery import RSD_PORT, RemoteServiceDiscoveryService, \ get_remoted_device, get_remoted_devices +from pymobiledevice3.remote.xpc_message import XpcInt64Type, XpcUInt64Type logger = logging.getLogger(__name__) -class RemoteCommand(click.Command): +class RemoteHostnameCommand(click.Command): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.params[:0] = [ @@ -43,6 +45,25 @@ def udid(ctx, param: str, value: str) -> Optional[str]: return prompt_device_list(device_options).hostname +class RemoteTunCommand(click.Command): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.params[:0] = [ + click.Option(('rsd', '--rsd'), callback=self.rsd, type=(str, int), required=True, + help='Target device hostname and port number for RSD connection'), + click.Option(('verbosity', '-v', '--verbose'), count=True, callback=set_verbosity, expose_value=False), + ] + + @staticmethod + def rsd(ctx, param: str, value: Tuple[str, int]) -> Optional[RemoteServiceDiscoveryService]: + if '_PYMOBILEDEVICE3_COMPLETE' in os.environ: + # prevent lockdown connection establishment when in autocomplete mode + return + + with RemoteServiceDiscoveryService(value) as rsd: + return rsd + + @click.group() def cli(): """ remote cli """ @@ -55,7 +76,7 @@ def remote_cli(): pass -@remote_cli.command('rsd-info', cls=RemoteCommand) +@remote_cli.command('rsd-info', cls=RemoteHostnameCommand) @click.option('--color/--no-color', default=True) def rsd_info(hostname: str, color: bool): """ show info extracted from RSD peer """ @@ -63,7 +84,7 @@ def rsd_info(hostname: str, color: bool): print_json(rsd.peer_info, colored=color) -@remote_cli.command('create-listener', cls=RemoteCommand) +@remote_cli.command('create-listener', cls=RemoteHostnameCommand) @click.option('-p', '--protocol', type=click.Choice(['quic', 'udp'])) @click.option('--color/--no-color', default=True) def create_listener(hostname: str, protocol: str, color: bool): @@ -74,7 +95,7 @@ def create_listener(hostname: str, protocol: str, color: bool): print_json(service.create_listener(private_key, protocol=protocol), colored=color) -@remote_cli.command('start-quic-tunnel', cls=RemoteCommand) +@remote_cli.command('start-quic-tunnel', cls=RemoteHostnameCommand) @click.option('--color/--no-color', default=True) def start_quic_tunnel(hostname: str, color: bool): """ start quic tunnel """ @@ -83,3 +104,57 @@ def start_quic_tunnel(hostname: str, color: bool): with RemoteServiceDiscoveryService((hostname, RSD_PORT)) as rsd: with create_core_device_tunnel_service(rsd, autopair=True) as service: print_json(asyncio.run(service.start_quic_tunnel(private_key)), colored=color) + + +@remote_cli.group() +def tun(): + pass + + +@tun.command('rsd-info', cls=RemoteTunCommand) +@click.option('--color/--no-color', default=True) +def tun_rsd_info(rsd: RemoteServiceDiscoveryService, color: bool): + """ show info extracted from RSD peer """ + print_json(rsd.peer_info, colored=color) + + +@tun.command('test', cls=RemoteTunCommand) +@click.option('--color/--no-color', default=True) +def test(rsd: RemoteServiceDiscoveryService, color: bool): + """ start quic tunnel """ + core_device = rsd.connect_to_service('com.apple.mobile.storage_mounter_proxy.bridge') + + response = core_device.send_receive_request({ + 'XPCRequestDictionary': {'Command': 'CopyDevices', + 'HostProcessName': 'CoreDeviceService'}}) + print(response) + + +@tun.command('test2', cls=RemoteTunCommand) +@click.option('--color/--no-color', default=True) +def test2(rsd: RemoteServiceDiscoveryService, color: bool): + """ start quic tunnel """ + core_device = rsd.connect_to_service('com.apple.syslog_relay.shim.remote') + print(core_device) + core_device.start_service('com.apple.syslog_relay') + print(core_device) + + +@tun.command('list-processes', cls=RemoteTunCommand) +@click.option('--color/--no-color', default=True) +def list_processes(rsd: RemoteServiceDiscoveryService, color: bool): + """ start quic tunnel """ + core_device = rsd.connect_to_service('com.apple.coredevice.appservice') + response = core_device.send_receive_request({ + 'CoreDevice.CoreDeviceDDIProtocolVersion': XpcInt64Type(0), + 'CoreDevice.action': {}, + 'CoreDevice.coreDeviceVersion': { + 'components': [XpcUInt64Type(325), XpcUInt64Type(3), XpcUInt64Type(0), + XpcUInt64Type(0), XpcUInt64Type(0)], + 'originalComponentsCount': XpcInt64Type(2), + 'stringValue': '325.3'}, + 'CoreDevice.deviceIdentifier': '7454ABFD-F789-4F99-9EE1-5FB8F7035ECE', + 'CoreDevice.featureIdentifier': 'com.apple.coredevice.feature.listprocesses', + 'CoreDevice.input': {}, + 'CoreDevice.invocationIdentifier': '94A17AB8-0576-4E73-94C6-C0282A4F66E3'}) + print(response) diff --git a/pymobiledevice3/lockdown.py b/pymobiledevice3/lockdown.py index 9380fb1c4..d57bd92fb 100755 --- a/pymobiledevice3/lockdown.py +++ b/pymobiledevice3/lockdown.py @@ -24,6 +24,7 @@ from pymobiledevice3.pair_records import create_pairing_records_cache_folder, generate_host_id, \ get_preferred_pair_record from pymobiledevice3.service_connection import ServiceConnection +from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider from pymobiledevice3.usbmux import PlistMuxConnection from pymobiledevice3.utils import sanitize_ios_version @@ -100,7 +101,7 @@ def _inner_reconnect_on_remote_close(*args, **kwargs): return _inner_reconnect_on_remote_close -class LockdownClient(ABC): +class LockdownClient(ABC, LockdownServiceProvider): def __init__(self, service: ServiceConnection, host_id: str, identifier: str = None, label: str = DEFAULT_LABEL, system_buid: str = SYSTEM_BUID, pair_record: Mapping = None, pairing_records_cache_folder: Path = None, port: int = SERVICE_PORT): @@ -430,8 +431,8 @@ def set_value(self, value, domain: str = None, key: str = None) -> Mapping: return self._request('SetValue', options) def get_service_connection_attributes(self, name, escrow_bag=None) -> Mapping: - if not self.paired: - raise NotPairedError() + # if not self.paired: + # raise NotPairedError() options = {'Service': name} if escrow_bag is not None: @@ -464,16 +465,6 @@ async def aio_start_service(self, name: str, escrow_bag=None) -> ServiceConnecti await service_connection.aio_ssl_start(f) return service_connection - def start_developer_service(self, name, escrow_bag=None) -> ServiceConnection: - try: - return self.start_service(name, escrow_bag) - except StartServiceError: - self.logger.error( - 'Failed to connect to required service. Make sure DeveloperDiskImage.dmg has been mounted. ' - 'You can do so using: pymobiledevice3 mounter mount' - ) - raise - def close(self) -> None: self.service.close() @@ -690,8 +681,8 @@ def create_using_remote(hostname: str, identifier: str = None, label: str = DEFA service.send_plist({'Label': label, 'ProtocolVersion': '2', 'Request': 'RSDCheckin'}) # we expect two responses after the first request - service.recv_plist() - service.recv_plist() + print(service.recv_plist()) + print(service.recv_plist()) client = TcpLockdownClient.create( service, identifier=identifier, label=label, local_hostname=local_hostname, pair_record=pair_record, diff --git a/pymobiledevice3/lockdown_service_provider.py b/pymobiledevice3/lockdown_service_provider.py new file mode 100644 index 000000000..8ec22e9a2 --- /dev/null +++ b/pymobiledevice3/lockdown_service_provider.py @@ -0,0 +1,24 @@ +import logging +from abc import abstractmethod + +from pymobiledevice3.exceptions import StartServiceError +from pymobiledevice3.service_connection import ServiceConnection + + +class LockdownServiceProvider: + @abstractmethod + def start_service(self, name: str, escrow_bag=None, **args) -> ServiceConnection: + pass + + async def aio_start_service(self, name: str, escrow_bag=None, **args) -> ServiceConnection: + pass + + def start_developer_service(self, name, escrow_bag=None, **args) -> ServiceConnection: + try: + return self.start_service(name, escrow_bag, **args) + except StartServiceError: + logging.getLogger(self.__module__).error( + 'Failed to connect to required service. Make sure DeveloperDiskImage.dmg has been mounted. ' + 'You can do so using: pymobiledevice3 mounter mount' + ) + raise diff --git a/pymobiledevice3/remote/remote_service_discovery.py b/pymobiledevice3/remote/remote_service_discovery.py index 5c3342c14..687a4faad 100644 --- a/pymobiledevice3/remote/remote_service_discovery.py +++ b/pymobiledevice3/remote/remote_service_discovery.py @@ -1,9 +1,11 @@ from dataclasses import dataclass -from typing import List, Tuple +from typing import List, Tuple, Union -from pymobiledevice3.exceptions import NoDeviceConnectedError +from pymobiledevice3.exceptions import NoDeviceConnectedError, PyMobileDevice3Exception from pymobiledevice3.remote.bonjour import DEFAULT_BONJOUR_TIMEOUT, get_remoted_addresses from pymobiledevice3.remote.remotexpc import RemoteXPCConnection +from pymobiledevice3.service_connection import ServiceConnection +from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider @dataclass @@ -18,7 +20,8 @@ class RSDDevice: RSD_PORT = 58783 -class RemoteServiceDiscoveryService: +class RemoteServiceDiscoveryService(LockdownServiceProvider): + def __init__(self, address: Tuple[str, int]): self.service = RemoteXPCConnection(address) self.peer_info = None @@ -27,9 +30,34 @@ def connect(self) -> None: self.service.connect() self.peer_info = self.service.receive_response() - def connect_to_service(self, name: str) -> RemoteXPCConnection: - service_port = int(self.peer_info['Services'][name]['Port']) - service = RemoteXPCConnection((self.service.address[0], service_port)) + def start_service(self, name: str, escrow_bag: bytes = None, + requires_rsd_checkin: bool = True) -> ServiceConnection: + return self.connect_to_service(name, escrow_bag=escrow_bag, requires_rsd_checkin=requires_rsd_checkin) + + def connect_to_service(self, name: str, escrow_bag: bytes = None, requires_rsd_checkin: bool = True) -> \ + Union[RemoteXPCConnection, ServiceConnection]: + service = self.peer_info['Services'][name] + service_port = int(service['Port']) + service_properties = service.get('Properties', {}) + use_remote_xpc = service_properties.get('UsesRemoteXPC', False) + service_version = service_properties.get('ServiceVersion') + if not use_remote_xpc: + service = ServiceConnection.create_using_tcp(self.service.address[0], service_port) + if requires_rsd_checkin: + checkin = {'Label': 'pymobiledevice3', 'ProtocolVersion': '2', 'Request': 'RSDCheckin'} + if escrow_bag is not None: + checkin['EscrowBag'] = escrow_bag + response = service.send_recv_plist(checkin) + if response['Request'] != 'RSDCheckin': + raise PyMobileDevice3Exception( + f'Invalid response for RSDCheckIn: {response}. Expected "RSDCheckIn"') + response = service.recv_plist() + if response['Request'] != 'StartService': + raise PyMobileDevice3Exception( + f'Invalid response for RSDCheckIn: {response}. Expected "ServiceService"') + return service + + service = RemoteXPCConnection((self.service.address[0], service_port), service_version) service.connect() return service diff --git a/pymobiledevice3/remote/remotexpc.py b/pymobiledevice3/remote/remotexpc.py index ef4ce657d..b046cef14 100644 --- a/pymobiledevice3/remote/remotexpc.py +++ b/pymobiledevice3/remote/remotexpc.py @@ -17,8 +17,9 @@ class RemoteXPCConnection: - def __init__(self, address: Tuple[str, int]): + def __init__(self, address: Tuple[str, int], service_version: int = 2): self.address = address + self.service_version = service_version self.sock: Optional[socket.socket] = None self.next_message_id = 0 self.peer_info = None diff --git a/pymobiledevice3/remote/xpc_message.py b/pymobiledevice3/remote/xpc_message.py index 9fa9590a4..c9a05c0c7 100644 --- a/pymobiledevice3/remote/xpc_message.py +++ b/pymobiledevice3/remote/xpc_message.py @@ -170,6 +170,7 @@ def _decode_xpc_object(xpc_object) -> Any: def get_object_from_xpc_wrapper(payload: bytes): payload = XpcWrapper.parse(payload).message.payload + # print(payload) if payload is None: return None return _decode_xpc_object(payload.obj) @@ -252,10 +253,12 @@ def _build_xpc_object(payload: Any) -> Mapping: return builder(payload) -def create_xpc_wrapper(d: Mapping, message_id: int = 0) -> bytes: +def create_xpc_wrapper(d: Mapping, message_id: int = 0, service_version=2) -> bytes: flags = XpcFlags.ALWAYS_SET if len(d.keys()) > 0: flags |= XpcFlags.DATA_PRESENT + if service_version == 1: + flags |= XpcFlags.HEARTBEAT_REQUEST xpc_payload = { 'message_id': message_id, diff --git a/pymobiledevice3/services/base_service.py b/pymobiledevice3/services/base_service.py index f61163974..0c8ce1394 100644 --- a/pymobiledevice3/services/base_service.py +++ b/pymobiledevice3/services/base_service.py @@ -1,12 +1,12 @@ import logging -from pymobiledevice3.lockdown import LockdownClient from pymobiledevice3.service_connection import ServiceConnection +from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider class BaseService: - def __init__(self, lockdown: LockdownClient, service_name: str, is_developer_service=False, - service: ServiceConnection = None): + def __init__(self, lockdown: LockdownServiceProvider, service_name: str, is_developer_service=False, + service: ServiceConnection = None, requires_rsd_checkin: bool = True): """ :param lockdown: lockdown connection :param service_name: wrapped service name - will attempt @@ -14,9 +14,9 @@ def __init__(self, lockdown: LockdownClient, service_name: str, is_developer_ser :param service: an established service connection object. If none, will attempt connecting to service_name """ - if not service: + if service is None: start_service = lockdown.start_developer_service if is_developer_service else lockdown.start_service - service = start_service(service_name) + service = start_service(service_name, requires_rsd_checkin=requires_rsd_checkin) self.service_name = service_name self.lockdown = lockdown diff --git a/pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py b/pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py index f6b957dbe..096581923 100644 --- a/pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +++ b/pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py @@ -1,14 +1,22 @@ +from typing import Union + from packaging.version import Version from pymobiledevice3.lockdown import LockdownClient +from pymobiledevice3.remote.remote_service_discovery import RemoteServiceDiscoveryService from pymobiledevice3.services.remote_server import RemoteServer class DvtSecureSocketProxyService(RemoteServer): SERVICE_NAME = 'com.apple.instruments.remoteserver.DVTSecureSocketProxy' OLD_SERVICE_NAME = 'com.apple.instruments.remoteserver' + RSD_SERVICE_NAME = 'com.apple.instruments.dtservicehub' + + def __init__(self, lockdown: Union[RemoteServiceDiscoveryService, LockdownClient]): + if isinstance(lockdown, RemoteServiceDiscoveryService): + super().__init__(lockdown, self.RSD_SERVICE_NAME, remove_ssl_context=False) + return - def __init__(self, lockdown: LockdownClient): if Version(lockdown.product_version) >= Version('14.0'): service_name = self.SERVICE_NAME remove_ssl_context = False diff --git a/pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py b/pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py index 9602ed61f..2ee9c949d 100644 --- a/pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +++ b/pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py @@ -9,6 +9,7 @@ from pykdebugparser.kd_buf_parser import RAW_VERSION2_BYTES from pymobiledevice3.exceptions import ExtractingStackshotError +from pymobiledevice3.lockdown import LockdownClient from pymobiledevice3.resources.dsc_uuid_map import get_dsc_map from pymobiledevice3.services.dvt.dvt_secure_socket_proxy import DvtSecureSocketProxyService from pymobiledevice3.services.dvt.instruments.device_info import DeviceInfo @@ -676,8 +677,14 @@ def get_time_config(dvt): mach_absolute_time = time_info[0] numer = time_info[1] denom = time_info[2] - usecs_since_epoch = dvt.lockdown.get_value(key='TimeIntervalSince1970') * 1000000 + + usecs_since_epoch = 0 + timezone_offset_from_utc = 0 + if isinstance(dvt.lockdown, LockdownClient): + usecs_since_epoch = dvt.lockdown.get_value(key='TimeIntervalSince1970') * 1000000 + timezone_offset_from_utc = dvt.lockdown.get_value(key='TimeZoneOffsetFromUTC') + return dict( numer=numer, denom=denom, mach_absolute_time=mach_absolute_time, usecs_since_epoch=usecs_since_epoch, - timezone=timezone(timedelta(seconds=dvt.lockdown.get_value(key='TimeZoneOffsetFromUTC'))) + timezone=timezone(timedelta(seconds=timezone_offset_from_utc)) ) diff --git a/pymobiledevice3/services/dvt/instruments/device_info.py b/pymobiledevice3/services/dvt/instruments/device_info.py index 082a192ea..71de07b47 100644 --- a/pymobiledevice3/services/dvt/instruments/device_info.py +++ b/pymobiledevice3/services/dvt/instruments/device_info.py @@ -60,8 +60,10 @@ def mach_time_info(self): def mach_kernel_name(self) -> str: return self.request_information('machKernelName') - def kpep_database(self) -> typing.Mapping: - return plistlib.loads(self.request_information('kpepDatabase')) + def kpep_database(self) -> typing.Optional[typing.Mapping]: + kpep_database = self.request_information('kpepDatabase') + if kpep_database is not None: + return plistlib.loads(kpep_database) def trace_codes(self): codes_file = self.request_information('traceCodesFile') diff --git a/pymobiledevice3/services/os_trace.py b/pymobiledevice3/services/os_trace.py index d0f8f92f8..d432a58d4 100644 --- a/pymobiledevice3/services/os_trace.py +++ b/pymobiledevice3/services/os_trace.py @@ -11,6 +11,7 @@ from pymobiledevice3.exceptions import PyMobileDevice3Exception from pymobiledevice3.lockdown import LockdownClient +from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider from pymobiledevice3.services.base_service import BaseService from pymobiledevice3.utils import try_decode @@ -71,10 +72,13 @@ class OsTraceService(BaseService): * Archive contain the contents are the `/var/db/diagnostics` directory """ SERVICE_NAME = 'com.apple.os_trace_relay' + RSD_SERVICE_NAME = 'com.apple.os_trace_relay.shim.remote' - def __init__(self, lockdown: LockdownClient): - super().__init__(lockdown, self.SERVICE_NAME) - self.logger = logging.getLogger(__name__) + def __init__(self, lockdown: LockdownServiceProvider): + if isinstance(lockdown, LockdownClient): + super().__init__(lockdown, self.SERVICE_NAME) + else: + super().__init__(lockdown, self.RSD_SERVICE_NAME) def get_pid_list(self): self.service.send_plist({'Request': 'PidList'}) diff --git a/pymobiledevice3/services/remote_server.py b/pymobiledevice3/services/remote_server.py index 209afb388..aae10a8cc 100644 --- a/pymobiledevice3/services/remote_server.py +++ b/pymobiledevice3/services/remote_server.py @@ -13,6 +13,7 @@ from pymobiledevice3.exceptions import DvtException, UnrecognizedSelectorError from pymobiledevice3.lockdown import LockdownClient +from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider from pymobiledevice3.services.base_service import BaseService SHELL_USAGE = ''' @@ -236,8 +237,8 @@ class RemoteServer(BaseService): INSTRUMENTS_MESSAGE_TYPE = 2 EXPECTS_REPLY_MASK = 0x1000 - def __init__(self, lockdown: LockdownClient, service_name, remove_ssl_context=True): - super().__init__(lockdown, service_name, is_developer_service=True) + def __init__(self, lockdown: LockdownServiceProvider, service_name, remove_ssl_context: bool = True): + super().__init__(lockdown, service_name, is_developer_service=True, requires_rsd_checkin=False) if remove_ssl_context and hasattr(self.service.socket, '_sslobj'): self.service.socket._sslobj = None diff --git a/pymobiledevice3/services/syslog.py b/pymobiledevice3/services/syslog.py index 78f1d7468..bfb1d482f 100644 --- a/pymobiledevice3/services/syslog.py +++ b/pymobiledevice3/services/syslog.py @@ -1,4 +1,5 @@ from pymobiledevice3.lockdown import LockdownClient +from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider from pymobiledevice3.services.base_service import BaseService from pymobiledevice3.utils import try_decode @@ -13,9 +14,13 @@ class SyslogService(BaseService): """ SERVICE_NAME = 'com.apple.syslog_relay' + RSD_SERVICE_NAME = 'com.apple.syslog_relay.shim.remote' - def __init__(self, lockdown: LockdownClient): - super().__init__(lockdown, self.SERVICE_NAME) + def __init__(self, lockdown: LockdownServiceProvider): + if isinstance(lockdown, LockdownClient): + super().__init__(lockdown, self.SERVICE_NAME) + else: + super().__init__(lockdown, self.RSD_SERVICE_NAME) def watch(self): buf = b''