pymobiledevice3 7.0.7__tar.gz → 7.2.0__tar.gz
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.
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/PKG-INFO +1 -1
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/_version.py +3 -3
- pymobiledevice3-7.2.0/pymobiledevice3/cli/developer/debugserver.py +279 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/dvt/__init__.py +26 -23
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3.egg-info/PKG-INFO +1 -1
- pymobiledevice3-7.0.7/pymobiledevice3/cli/developer/debugserver.py +0 -244
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.gitattributes +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/FUNDING.yml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/pull_request_template.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/workflows/codeql.yml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/workflows/generate-executable.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/workflows/markdown-lint.yml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/workflows/python-app.yml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.github/workflows/python-publish.yml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.gitignore +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/.pre-commit-config.yaml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/CODE_OF_CONDUCT.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/CONTRIBUTING.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/LICENSE +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/README.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/example.gif +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/markdownlint-config.json +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/DTServices-14.2.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/DTServices-14.5.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/RemoteXPC.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/plist_sniffer.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/pyinstaller.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/remotexpc_sniffer.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/understanding_idevice_protocol_layers.md +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/misc/usbmux_sniff.sh +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/__main__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/bonjour.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/ca.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/activation.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/afc.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/amfi.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/apps.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/backup.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/bonjour.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/cli_common.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/companion_proxy.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/crash.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/accessibility/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/accessibility/settings.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/arbitration.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/condition.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/core_device.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/dvt/core_profile_session.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/dvt/simulate_location.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/dvt/sysmon/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/dvt/sysmon/process.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/fetch_symbols.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/simulate_location.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/diagnostics/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/diagnostics/battery.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/idam.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/lockdown.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/mounter.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/notification.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/pcap.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/power_assertion.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/processes.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/profile.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/provision.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/remote.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/restore.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/springboard.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/syslog.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/usbmux.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/version.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/webinspector.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/common.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/exceptions.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/irecv.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/irecv_devices.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/lockdown.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/lockdown_service_provider.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/osu/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/osu/os_utils.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/osu/posix_util.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/osu/win_util.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/pair_records.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/common.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/core_device/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/core_device/app_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/core_device/core_device_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/core_device/device_info.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/core_device/diagnostics_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/core_device/file_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/module_imports.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/remote_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/remote_service_discovery.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/remotexpc.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/tunnel_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/utils.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/remote/xpc_message.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/dsc_uuid_map.json +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/dsc_uuid_map.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/firmware_notifications.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/notifications.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/element_attribute.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/element_clear.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/enter_fullscreen.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/find_nodes.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/focus.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/get_attribute.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/is_displayed.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/is_editable.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/resources/webinspector/is_enabled.js +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/asr.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/base_restore.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/consts.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/device.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/fdr.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/ftab.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/img4.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/mbn.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/recovery.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/restore.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/restore_options.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/restored_client.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/restore/tss.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/service_connection.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/accessibilityaudit.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/afc.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/amfi.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/companion.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/crash_reports.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/debugserver_applist.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/device_arbitration.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/device_link.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/diagnostics.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dtfetchsymbols.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/dvt_secure_socket_proxy.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/dvt_testmanaged_proxy.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/activity_trace_tap.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/application_listing.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/condition_inducer.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/core_profile_session_tap.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/device_info.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/energy_monitor.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/graphics.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/location_simulation.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/location_simulation_base.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/network_monitor.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/notifications.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/process_control.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/screenshot.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/instruments/sysmontap.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/dvt/testmanaged/xcuitest.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/file_relay.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/heartbeat.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/house_arrest.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/idam.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/installation_proxy.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/lockdown_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/misagent.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/mobile_activation.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/mobile_config.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/mobile_image_mounter.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/mobilebackup2.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/notification_proxy.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/os_trace.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/pcapd.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/power_assertion.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/preboard.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/remote_fetch_symbols.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/remote_server.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/restore_service.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/screenshot.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/simulate_location.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/springboard.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/syslog.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/alert.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/automation_session.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/cdp_screencast.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/cdp_server.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/cdp_target.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/driver.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/element.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/inspector_session.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/selenium_api.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/session_protocol.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/web_protocol/switch_to.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/services/webinspector.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/tcp_forwarder.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/tunneld/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/tunneld/api.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/tunneld/server.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/usbmux.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/utils.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3.egg-info/SOURCES.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3.egg-info/dependency_links.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3.egg-info/entry_points.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3.egg-info/requires.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3.egg-info/top_level.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pyproject.toml +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pytest.ini +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/requirements.txt +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/setup.cfg +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/cli/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/cli/test_cli.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/conftest.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/instruments/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/instruments/test_core_profile_session.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/instruments/test_dvt_secure_socket_proxy.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/instruments/test_fetch_symbols.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/instruments/test_location.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/instruments/test_screenshot.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_accessibility.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_afc.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_apps.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_backup2.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_bonjour.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_crash_reports.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_house_arrest.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_list_devices.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_lockdown.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_pcapd.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_springboard_services_relay.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_start_tunnel.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_syslog_relay.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_tcp_forwarder.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_web_protocol/__init__.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_web_protocol/common.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_web_protocol/conftest.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_web_protocol/test_driver.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_web_protocol/test_element.py +0 -0
- {pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/tests/services/test_webinspector.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pymobiledevice3
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.2.0
|
|
4
4
|
Summary: Pure python3 implementation for working with iDevices (iPhone, etc...)
|
|
5
5
|
Author-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
|
|
6
6
|
Maintainer-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '7.0
|
|
32
|
-
__version_tuple__ = version_tuple = (7,
|
|
31
|
+
__version__ = version = '7.2.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (7, 2, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'ge03294729'
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import plistlib
|
|
4
|
+
import signal
|
|
5
|
+
import struct
|
|
6
|
+
import subprocess
|
|
7
|
+
import sys
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from tempfile import TemporaryDirectory
|
|
10
|
+
from typing import Annotated, Optional
|
|
11
|
+
from zipfile import ZipFile
|
|
12
|
+
|
|
13
|
+
import typer
|
|
14
|
+
from packaging.version import Version
|
|
15
|
+
from plumbum import local
|
|
16
|
+
from typer_injector import InjectingTyper
|
|
17
|
+
|
|
18
|
+
from pymobiledevice3.cli.cli_common import RSDServiceProviderDep, ServiceProviderDep, print_json
|
|
19
|
+
from pymobiledevice3.exceptions import RSDRequiredError
|
|
20
|
+
from pymobiledevice3.lockdown import create_using_usbmux
|
|
21
|
+
from pymobiledevice3.remote.remote_service_discovery import RemoteServiceDiscoveryService
|
|
22
|
+
from pymobiledevice3.services.debugserver_applist import DebugServerAppList
|
|
23
|
+
from pymobiledevice3.services.installation_proxy import InstallationProxyService
|
|
24
|
+
from pymobiledevice3.tcp_forwarder import LockdownTcpForwarder
|
|
25
|
+
|
|
26
|
+
DEBUGSERVER_CONNECTION_STEPS = """
|
|
27
|
+
Follow the following connections steps from LLDB:
|
|
28
|
+
|
|
29
|
+
(lldb) platform select remote-ios
|
|
30
|
+
(lldb) target create /path/to/local/application.app
|
|
31
|
+
(lldb) script lldb.target.module[0].SetPlatformFileSpec(lldb.SBFileSpec('/private/var/containers/Bundle/Application/<APP-UUID>/application.app'))
|
|
32
|
+
(lldb) process connect connect://[{host}]:{port} <-- ACTUAL CONNECTION DETAILS!
|
|
33
|
+
(lldb) process launch
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
logger = logging.getLogger(__name__)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
cli = InjectingTyper(
|
|
41
|
+
name="debugserver",
|
|
42
|
+
help="Start and drive debugserver sessions (RSD for iOS 17+, usbmux for older).",
|
|
43
|
+
no_args_is_help=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@cli.command("applist")
|
|
48
|
+
def debugserver_applist(service_provider: ServiceProviderDep) -> None:
|
|
49
|
+
"""Print the debugserver applist XML for the device."""
|
|
50
|
+
print_json(DebugServerAppList(service_provider).get())
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@cli.command("start-server")
|
|
54
|
+
def debugserver_start_server(service_provider: ServiceProviderDep, local_port: Optional[int] = None) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Start debugserver and print the LLDB connect string.
|
|
57
|
+
|
|
58
|
+
- For iOS < 17, you must forward to a local port (--local-port).
|
|
59
|
+
- For iOS >= 17, if connected over RSD, the remote host:port is printed for LLDB.
|
|
60
|
+
Connect quickly with your own LLDB client using the printed steps.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
if Version(service_provider.product_version) < Version("17.0"):
|
|
64
|
+
service_name = "com.apple.debugserver.DVTSecureSocketProxy"
|
|
65
|
+
else:
|
|
66
|
+
service_name = "com.apple.internal.dt.remote.debugproxy"
|
|
67
|
+
|
|
68
|
+
if local_port is not None:
|
|
69
|
+
print(DEBUGSERVER_CONNECTION_STEPS.format(host="127.0.0.1", port=local_port))
|
|
70
|
+
print("Started port forwarding. Press Ctrl-C to close this shell when done")
|
|
71
|
+
sys.stdout.flush()
|
|
72
|
+
LockdownTcpForwarder(service_provider, local_port, service_name).start()
|
|
73
|
+
elif Version(service_provider.product_version) >= Version("17.0"):
|
|
74
|
+
if not isinstance(service_provider, RemoteServiceDiscoveryService):
|
|
75
|
+
raise RSDRequiredError(service_provider.identifier)
|
|
76
|
+
debugserver_port = service_provider.get_service_port(service_name)
|
|
77
|
+
print(DEBUGSERVER_CONNECTION_STEPS.format(host=service_provider.service.address[0], port=debugserver_port))
|
|
78
|
+
else:
|
|
79
|
+
print("local_port is required for iOS < 17.0")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@cli.command("lldb")
|
|
83
|
+
def debugserver_lldb(
|
|
84
|
+
service_provider: RSDServiceProviderDep,
|
|
85
|
+
project_or_ipa_path: Annotated[
|
|
86
|
+
Path,
|
|
87
|
+
typer.Argument(exists=True, file_okay=True, dir_okay=True),
|
|
88
|
+
],
|
|
89
|
+
configuration: Annotated[
|
|
90
|
+
str,
|
|
91
|
+
typer.Option(help="Build configuration to invoke (e.g., Debug or Release)."),
|
|
92
|
+
] = "Debug",
|
|
93
|
+
lldb_command: Annotated[
|
|
94
|
+
str,
|
|
95
|
+
typer.Option(help="Path to the lldb executable to run."),
|
|
96
|
+
] = "lldb",
|
|
97
|
+
launch: Annotated[
|
|
98
|
+
bool,
|
|
99
|
+
typer.Option(help="Automatically launch the app after attaching."),
|
|
100
|
+
] = False,
|
|
101
|
+
breakpoints: Annotated[
|
|
102
|
+
Optional[list[str]],
|
|
103
|
+
typer.Option("--break", "-b", help="Add multiple startup breakpoints"),
|
|
104
|
+
] = None,
|
|
105
|
+
user_commands: Annotated[
|
|
106
|
+
Optional[list[str]],
|
|
107
|
+
typer.Option("--command", "-c", help="Additional commands to run at startup"),
|
|
108
|
+
] = None,
|
|
109
|
+
) -> None:
|
|
110
|
+
"""
|
|
111
|
+
Automate lldb launch for a given xcodeproj or IPA.
|
|
112
|
+
|
|
113
|
+
\b
|
|
114
|
+
This will:
|
|
115
|
+
- Build the given xcodeproj (if provided)
|
|
116
|
+
- Extract the given IPA (if provided)
|
|
117
|
+
- Install it
|
|
118
|
+
- Start a debugserver attached to it
|
|
119
|
+
- Place breakpoints if given any
|
|
120
|
+
- Launch the application if requested
|
|
121
|
+
- Execute any additional commands if requested
|
|
122
|
+
- Switch to lldb shell
|
|
123
|
+
"""
|
|
124
|
+
if Version(service_provider.product_version) < Version("17.0"):
|
|
125
|
+
logger.error("lldb is only supported on iOS >= 17.0")
|
|
126
|
+
return
|
|
127
|
+
|
|
128
|
+
commands = []
|
|
129
|
+
temp_dir = None
|
|
130
|
+
local_app = None
|
|
131
|
+
install_source = None
|
|
132
|
+
|
|
133
|
+
if project_or_ipa_path.suffix == ".xcodeproj":
|
|
134
|
+
with local.cwd(project_or_ipa_path.parent):
|
|
135
|
+
logger.info(f"Building {project_or_ipa_path} for {configuration} configuration")
|
|
136
|
+
local["xcodebuild"]["-project", str(project_or_ipa_path), "-configuration", configuration, "build"]()
|
|
137
|
+
app_candidates = [app for app in Path("build").rglob("*.app") if (app / "Info.plist").exists()]
|
|
138
|
+
if not app_candidates:
|
|
139
|
+
logger.error("No built .app with Info.plist found under build/.")
|
|
140
|
+
return
|
|
141
|
+
app_candidates.sort(key=lambda p: p.stat().st_mtime, reverse=True)
|
|
142
|
+
local_app = app_candidates[0].absolute()
|
|
143
|
+
install_source = local_app
|
|
144
|
+
elif project_or_ipa_path.suffix == ".ipa":
|
|
145
|
+
temp_dir = TemporaryDirectory()
|
|
146
|
+
with ZipFile(project_or_ipa_path, "r") as ipa_zip:
|
|
147
|
+
ipa_zip.extractall(temp_dir.name)
|
|
148
|
+
payload_dir = Path(temp_dir.name) / "Payload"
|
|
149
|
+
apps = list(payload_dir.glob("*.app"))
|
|
150
|
+
if not apps:
|
|
151
|
+
logger.error("No .app bundle found in IPA Payload.")
|
|
152
|
+
temp_dir.cleanup()
|
|
153
|
+
return
|
|
154
|
+
if len(apps) > 1:
|
|
155
|
+
logger.error("Multiple .app bundles found in IPA Payload; please provide a single-app IPA.")
|
|
156
|
+
temp_dir.cleanup()
|
|
157
|
+
return
|
|
158
|
+
local_app = apps[0].absolute()
|
|
159
|
+
install_source = project_or_ipa_path
|
|
160
|
+
else:
|
|
161
|
+
logger.error("Expected an .xcodeproj directory or an .ipa file.")
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
logger.info(f"Using app: {local_app}")
|
|
165
|
+
|
|
166
|
+
info_plist_path = local_app / "Info.plist"
|
|
167
|
+
info_plist = plistlib.loads(info_plist_path.read_bytes())
|
|
168
|
+
bundle_identifier = info_plist["CFBundleIdentifier"]
|
|
169
|
+
logger.info(f"Bundle identifier: {bundle_identifier}")
|
|
170
|
+
|
|
171
|
+
commands.append("platform select remote-ios")
|
|
172
|
+
commands.append(f'target create "{local_app.absolute()}"')
|
|
173
|
+
|
|
174
|
+
with InstallationProxyService(create_using_usbmux()) as installation_proxy:
|
|
175
|
+
logger.info("Installing app")
|
|
176
|
+
installation_proxy.install_from_local(install_source)
|
|
177
|
+
remote_path = installation_proxy.get_apps(bundle_identifiers=[bundle_identifier])[bundle_identifier]["Path"]
|
|
178
|
+
logger.info(f"Remote path: {remote_path}")
|
|
179
|
+
commands.append(f'script lldb.target.module[0].SetPlatformFileSpec(lldb.SBFileSpec("{remote_path}"))')
|
|
180
|
+
|
|
181
|
+
debugserver_port = service_provider.get_service_port("com.apple.internal.dt.remote.debugproxy")
|
|
182
|
+
|
|
183
|
+
# Add connection and launch commands
|
|
184
|
+
commands.append(f"process connect connect://[{service_provider.service.address[0]}]:{debugserver_port}")
|
|
185
|
+
|
|
186
|
+
if breakpoints:
|
|
187
|
+
for bp in breakpoints:
|
|
188
|
+
commands.append(f'breakpoint set -n "{bp}"')
|
|
189
|
+
|
|
190
|
+
if launch:
|
|
191
|
+
commands.append("process launch")
|
|
192
|
+
|
|
193
|
+
if user_commands:
|
|
194
|
+
# Add user commands
|
|
195
|
+
commands += user_commands
|
|
196
|
+
|
|
197
|
+
logger.info("Starting lldb with automated setup and connection")
|
|
198
|
+
|
|
199
|
+
# Works only on unix-based systems, so keep these imports here
|
|
200
|
+
import fcntl
|
|
201
|
+
import pty
|
|
202
|
+
import select as select_module
|
|
203
|
+
import termios
|
|
204
|
+
import tty
|
|
205
|
+
|
|
206
|
+
master, slave = pty.openpty()
|
|
207
|
+
|
|
208
|
+
process = None # Initialize process variable for signal handler
|
|
209
|
+
|
|
210
|
+
# Copy terminal size from the current terminal to PTY
|
|
211
|
+
def resize_pty() -> None:
|
|
212
|
+
"""Update PTY size to match current terminal size"""
|
|
213
|
+
size = struct.unpack(
|
|
214
|
+
"HHHH", fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0))
|
|
215
|
+
)
|
|
216
|
+
fcntl.ioctl(master, termios.TIOCSWINSZ, struct.pack("HHHH", *size))
|
|
217
|
+
# Send SIGWINCH to the child process to notify it of the resize
|
|
218
|
+
if process is not None and process.poll() is None:
|
|
219
|
+
process.send_signal(signal.SIGWINCH)
|
|
220
|
+
|
|
221
|
+
# Initial resize
|
|
222
|
+
resize_pty()
|
|
223
|
+
|
|
224
|
+
# Set up signal handler for window resize
|
|
225
|
+
def handle_sigwinch(signum, frame):
|
|
226
|
+
resize_pty()
|
|
227
|
+
|
|
228
|
+
old_sigwinch_handler = signal.signal(signal.SIGWINCH, handle_sigwinch)
|
|
229
|
+
|
|
230
|
+
# Save original terminal settings
|
|
231
|
+
old_tty = termios.tcgetattr(sys.stdin)
|
|
232
|
+
|
|
233
|
+
try:
|
|
234
|
+
# Set TERM environment variable to enable colors
|
|
235
|
+
env = os.environ.copy()
|
|
236
|
+
env["TERM"] = os.environ.get("TERM", "xterm-256color")
|
|
237
|
+
|
|
238
|
+
process = subprocess.Popen([lldb_command], stdin=slave, stdout=slave, stderr=slave, env=env)
|
|
239
|
+
os.close(slave)
|
|
240
|
+
|
|
241
|
+
# Put terminal in raw mode for proper interaction
|
|
242
|
+
tty.setraw(sys.stdin.fileno())
|
|
243
|
+
# Send all commands through stdin
|
|
244
|
+
for command in commands:
|
|
245
|
+
os.write(master, (command + "\n").encode())
|
|
246
|
+
|
|
247
|
+
# Now redirect stdin from the terminal to lldb so user can interact
|
|
248
|
+
while True:
|
|
249
|
+
rlist, _, _ = select_module.select([sys.stdin, master], [], [])
|
|
250
|
+
|
|
251
|
+
if sys.stdin in rlist:
|
|
252
|
+
# User typed something
|
|
253
|
+
data = os.read(sys.stdin.fileno(), 1024)
|
|
254
|
+
if not data:
|
|
255
|
+
break
|
|
256
|
+
os.write(master, data)
|
|
257
|
+
|
|
258
|
+
if master in rlist:
|
|
259
|
+
# lldb has output
|
|
260
|
+
try:
|
|
261
|
+
data = os.read(master, 1024)
|
|
262
|
+
if not data:
|
|
263
|
+
break
|
|
264
|
+
os.write(sys.stdout.fileno(), data)
|
|
265
|
+
except OSError:
|
|
266
|
+
break
|
|
267
|
+
except (KeyboardInterrupt, OSError):
|
|
268
|
+
pass
|
|
269
|
+
finally:
|
|
270
|
+
# Restore terminal settings
|
|
271
|
+
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
|
|
272
|
+
# Restore original SIGWINCH handler
|
|
273
|
+
signal.signal(signal.SIGWINCH, old_sigwinch_handler)
|
|
274
|
+
os.close(master)
|
|
275
|
+
if process is not None:
|
|
276
|
+
process.terminate()
|
|
277
|
+
process.wait()
|
|
278
|
+
if temp_dir is not None:
|
|
279
|
+
temp_dir.cleanup()
|
{pymobiledevice3-7.0.7 → pymobiledevice3-7.2.0}/pymobiledevice3/cli/developer/dvt/__init__.py
RENAMED
|
@@ -166,46 +166,49 @@ def process_id_for_bundle_id(service_provider: ServiceProviderDep, app_bundle_id
|
|
|
166
166
|
|
|
167
167
|
|
|
168
168
|
def get_matching_processes(
|
|
169
|
-
|
|
169
|
+
device_info: DeviceInfo,
|
|
170
170
|
name: Optional[str] = None,
|
|
171
171
|
bundle_identifier: Optional[str] = None,
|
|
172
172
|
) -> list[MatchedProcessByPid]:
|
|
173
173
|
result: list[MatchedProcessByPid] = []
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
):
|
|
183
|
-
result.append(MatchedProcessByPid(name=current_name, pid=pid))
|
|
174
|
+
for process in device_info.proclist():
|
|
175
|
+
current_name = process["name"]
|
|
176
|
+
current_bundle_identifier = process.get("bundleIdentifier", "")
|
|
177
|
+
pid = process["pid"]
|
|
178
|
+
if (bundle_identifier is not None and bundle_identifier in current_bundle_identifier) or (
|
|
179
|
+
name is not None and name in current_name
|
|
180
|
+
):
|
|
181
|
+
result.append(MatchedProcessByPid(name=current_name, pid=pid))
|
|
184
182
|
return result
|
|
185
183
|
|
|
186
184
|
|
|
187
185
|
@cli.command("pkill")
|
|
188
186
|
def pkill(
|
|
189
187
|
service_provider: ServiceProviderDep,
|
|
190
|
-
|
|
188
|
+
expressions: Annotated[
|
|
189
|
+
list[str],
|
|
190
|
+
typer.Argument(help="One or more process-name (or bundle id) expressions to match."),
|
|
191
|
+
],
|
|
191
192
|
bundle: Annotated[
|
|
192
193
|
bool,
|
|
193
|
-
typer.Option(help="Treat given
|
|
194
|
+
typer.Option(help="Treat given expressions as bundle-identifiers instead of process names"),
|
|
194
195
|
] = False,
|
|
195
196
|
) -> None:
|
|
196
|
-
"""Kill all processes containing
|
|
197
|
-
matching_name = expression if not bundle else None
|
|
198
|
-
matching_bundle_identifier = expression if bundle else None
|
|
199
|
-
matching_processes = get_matching_processes(
|
|
200
|
-
service_provider, name=matching_name, bundle_identifier=matching_bundle_identifier
|
|
201
|
-
)
|
|
202
|
-
|
|
197
|
+
"""Kill all processes containing each expression in their name."""
|
|
203
198
|
with DvtSecureSocketProxyService(lockdown=service_provider) as dvt:
|
|
199
|
+
device_info = DeviceInfo(dvt)
|
|
204
200
|
process_control = ProcessControl(dvt)
|
|
205
201
|
|
|
206
|
-
for
|
|
207
|
-
|
|
208
|
-
|
|
202
|
+
for expression in expressions:
|
|
203
|
+
matching_name = expression if not bundle else None
|
|
204
|
+
matching_bundle_identifier = expression if bundle else None
|
|
205
|
+
matching_processes = get_matching_processes(
|
|
206
|
+
device_info, name=matching_name, bundle_identifier=matching_bundle_identifier
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
for process in matching_processes:
|
|
210
|
+
logger.info(f"Killing {process.name}({process.pid})")
|
|
211
|
+
process_control.kill(process.pid)
|
|
209
212
|
|
|
210
213
|
|
|
211
214
|
@cli.command("launch")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pymobiledevice3
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.2.0
|
|
4
4
|
Summary: Pure python3 implementation for working with iDevices (iPhone, etc...)
|
|
5
5
|
Author-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
|
|
6
6
|
Maintainer-email: doronz88 <doron88@gmail.com>, matan <matan1008@gmail.com>
|
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
import os
|
|
3
|
-
import plistlib
|
|
4
|
-
import signal
|
|
5
|
-
import struct
|
|
6
|
-
import subprocess
|
|
7
|
-
import sys
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Annotated, Optional
|
|
10
|
-
|
|
11
|
-
import typer
|
|
12
|
-
from packaging.version import Version
|
|
13
|
-
from plumbum import local
|
|
14
|
-
from typer_injector import InjectingTyper
|
|
15
|
-
|
|
16
|
-
from pymobiledevice3.cli.cli_common import RSDServiceProviderDep, ServiceProviderDep, print_json
|
|
17
|
-
from pymobiledevice3.exceptions import RSDRequiredError
|
|
18
|
-
from pymobiledevice3.lockdown import create_using_usbmux
|
|
19
|
-
from pymobiledevice3.remote.remote_service_discovery import RemoteServiceDiscoveryService
|
|
20
|
-
from pymobiledevice3.services.debugserver_applist import DebugServerAppList
|
|
21
|
-
from pymobiledevice3.services.installation_proxy import InstallationProxyService
|
|
22
|
-
from pymobiledevice3.tcp_forwarder import LockdownTcpForwarder
|
|
23
|
-
|
|
24
|
-
DEBUGSERVER_CONNECTION_STEPS = """
|
|
25
|
-
Follow the following connections steps from LLDB:
|
|
26
|
-
|
|
27
|
-
(lldb) platform select remote-ios
|
|
28
|
-
(lldb) target create /path/to/local/application.app
|
|
29
|
-
(lldb) script lldb.target.module[0].SetPlatformFileSpec(lldb.SBFileSpec('/private/var/containers/Bundle/Application/<APP-UUID>/application.app'))
|
|
30
|
-
(lldb) process connect connect://[{host}]:{port} <-- ACTUAL CONNECTION DETAILS!
|
|
31
|
-
(lldb) process launch
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
logger = logging.getLogger(__name__)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
cli = InjectingTyper(
|
|
39
|
-
name="debugserver",
|
|
40
|
-
help="Start and drive debugserver sessions (RSD for iOS 17+, usbmux for older).",
|
|
41
|
-
no_args_is_help=True,
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@cli.command("applist")
|
|
46
|
-
def debugserver_applist(service_provider: ServiceProviderDep) -> None:
|
|
47
|
-
"""Print the debugserver applist XML for the device."""
|
|
48
|
-
print_json(DebugServerAppList(service_provider).get())
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
@cli.command("start-server")
|
|
52
|
-
def debugserver_start_server(service_provider: ServiceProviderDep, local_port: Optional[int] = None) -> None:
|
|
53
|
-
"""
|
|
54
|
-
Start debugserver and print the LLDB connect string.
|
|
55
|
-
|
|
56
|
-
- For iOS < 17, you must forward to a local port (--local-port).
|
|
57
|
-
- For iOS >= 17, if connected over RSD, the remote host:port is printed for LLDB.
|
|
58
|
-
Connect quickly with your own LLDB client using the printed steps.
|
|
59
|
-
"""
|
|
60
|
-
|
|
61
|
-
if Version(service_provider.product_version) < Version("17.0"):
|
|
62
|
-
service_name = "com.apple.debugserver.DVTSecureSocketProxy"
|
|
63
|
-
else:
|
|
64
|
-
service_name = "com.apple.internal.dt.remote.debugproxy"
|
|
65
|
-
|
|
66
|
-
if local_port is not None:
|
|
67
|
-
print(DEBUGSERVER_CONNECTION_STEPS.format(host="127.0.0.1", port=local_port))
|
|
68
|
-
print("Started port forwarding. Press Ctrl-C to close this shell when done")
|
|
69
|
-
sys.stdout.flush()
|
|
70
|
-
LockdownTcpForwarder(service_provider, local_port, service_name).start()
|
|
71
|
-
elif Version(service_provider.product_version) >= Version("17.0"):
|
|
72
|
-
if not isinstance(service_provider, RemoteServiceDiscoveryService):
|
|
73
|
-
raise RSDRequiredError(service_provider.identifier)
|
|
74
|
-
debugserver_port = service_provider.get_service_port(service_name)
|
|
75
|
-
print(DEBUGSERVER_CONNECTION_STEPS.format(host=service_provider.service.address[0], port=debugserver_port))
|
|
76
|
-
else:
|
|
77
|
-
print("local_port is required for iOS < 17.0")
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
@cli.command("lldb")
|
|
81
|
-
def debugserver_lldb(
|
|
82
|
-
service_provider: RSDServiceProviderDep,
|
|
83
|
-
xcodeproj_path: Annotated[
|
|
84
|
-
Path,
|
|
85
|
-
typer.Argument(exists=True, file_okay=False, dir_okay=True),
|
|
86
|
-
],
|
|
87
|
-
configuration: Annotated[
|
|
88
|
-
str,
|
|
89
|
-
typer.Option(help="Build configuration to invoke (e.g., Debug or Release)."),
|
|
90
|
-
] = "Debug",
|
|
91
|
-
lldb_command: Annotated[
|
|
92
|
-
str,
|
|
93
|
-
typer.Option(help="Path to the lldb executable to run."),
|
|
94
|
-
] = "lldb",
|
|
95
|
-
launch: Annotated[
|
|
96
|
-
bool,
|
|
97
|
-
typer.Option(help="Automatically launch the app after attaching."),
|
|
98
|
-
] = False,
|
|
99
|
-
breakpoints: Annotated[
|
|
100
|
-
Optional[list[str]],
|
|
101
|
-
typer.Option("--break", "-b", help="Add multiple startup breakpoints"),
|
|
102
|
-
] = None,
|
|
103
|
-
user_commands: Annotated[
|
|
104
|
-
Optional[list[str]],
|
|
105
|
-
typer.Option("--command", "-c", help="Additional commands to run at startup"),
|
|
106
|
-
] = None,
|
|
107
|
-
) -> None:
|
|
108
|
-
"""
|
|
109
|
-
Automate lldb launch for a given xcodeproj.
|
|
110
|
-
|
|
111
|
-
\b
|
|
112
|
-
This will:
|
|
113
|
-
- Build the given xcodeproj
|
|
114
|
-
- Install it
|
|
115
|
-
- Start a debugserver attached to it
|
|
116
|
-
- Place breakpoints if given any
|
|
117
|
-
- Launch the application if requested
|
|
118
|
-
- Execute any additional commands if requested
|
|
119
|
-
- Switch to lldb shell
|
|
120
|
-
"""
|
|
121
|
-
if Version(service_provider.product_version) < Version("17.0"):
|
|
122
|
-
logger.error("lldb is only supported on iOS >= 17.0")
|
|
123
|
-
return
|
|
124
|
-
|
|
125
|
-
commands = []
|
|
126
|
-
with local.cwd(xcodeproj_path.parent):
|
|
127
|
-
logger.info(f"Building {xcodeproj_path} for {configuration} configuration")
|
|
128
|
-
local["xcodebuild"]["-configuration", configuration, "build"]()
|
|
129
|
-
local_app = next(iter(Path(f"build/{configuration}-iphoneos").glob("*.app")))
|
|
130
|
-
logger.info(f"Using app: {local_app}")
|
|
131
|
-
|
|
132
|
-
info_plist_path = local_app / "Info.plist"
|
|
133
|
-
info_plist = plistlib.loads(info_plist_path.read_bytes())
|
|
134
|
-
bundle_identifier = info_plist["CFBundleIdentifier"]
|
|
135
|
-
logger.info(f"Bundle identifier: {bundle_identifier}")
|
|
136
|
-
|
|
137
|
-
commands.append("platform select remote-ios")
|
|
138
|
-
commands.append(f'target create "{local_app.absolute()}"')
|
|
139
|
-
|
|
140
|
-
with InstallationProxyService(create_using_usbmux()) as installation_proxy:
|
|
141
|
-
logger.info("Installing app")
|
|
142
|
-
installation_proxy.install_from_local(local_app)
|
|
143
|
-
remote_path = installation_proxy.get_apps(bundle_identifiers=[bundle_identifier])[bundle_identifier]["Path"]
|
|
144
|
-
logger.info(f"Remote path: {remote_path}")
|
|
145
|
-
|
|
146
|
-
commands.append(f'script lldb.target.module[0].SetPlatformFileSpec(lldb.SBFileSpec("{remote_path}"))')
|
|
147
|
-
|
|
148
|
-
debugserver_port = service_provider.get_service_port("com.apple.internal.dt.remote.debugproxy")
|
|
149
|
-
|
|
150
|
-
# Add connection and launch commands
|
|
151
|
-
commands.append(f"process connect connect://[{service_provider.service.address[0]}]:{debugserver_port}")
|
|
152
|
-
|
|
153
|
-
if breakpoints:
|
|
154
|
-
for bp in breakpoints:
|
|
155
|
-
commands.append(f'breakpoint set -n "{bp}"')
|
|
156
|
-
|
|
157
|
-
if launch:
|
|
158
|
-
commands.append("process launch")
|
|
159
|
-
|
|
160
|
-
if user_commands:
|
|
161
|
-
# Add user commands
|
|
162
|
-
commands += user_commands
|
|
163
|
-
|
|
164
|
-
logger.info("Starting lldb with automated setup and connection")
|
|
165
|
-
|
|
166
|
-
# Works only on unix-based systems, so keep these imports here
|
|
167
|
-
import fcntl
|
|
168
|
-
import pty
|
|
169
|
-
import select as select_module
|
|
170
|
-
import termios
|
|
171
|
-
import tty
|
|
172
|
-
|
|
173
|
-
master, slave = pty.openpty()
|
|
174
|
-
|
|
175
|
-
process = None # Initialize process variable for signal handler
|
|
176
|
-
|
|
177
|
-
# Copy terminal size from the current terminal to PTY
|
|
178
|
-
def resize_pty() -> None:
|
|
179
|
-
"""Update PTY size to match current terminal size"""
|
|
180
|
-
size = struct.unpack(
|
|
181
|
-
"HHHH", fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0))
|
|
182
|
-
)
|
|
183
|
-
fcntl.ioctl(master, termios.TIOCSWINSZ, struct.pack("HHHH", *size))
|
|
184
|
-
# Send SIGWINCH to the child process to notify it of the resize
|
|
185
|
-
if process is not None and process.poll() is None:
|
|
186
|
-
process.send_signal(signal.SIGWINCH)
|
|
187
|
-
|
|
188
|
-
# Initial resize
|
|
189
|
-
resize_pty()
|
|
190
|
-
|
|
191
|
-
# Set up signal handler for window resize
|
|
192
|
-
def handle_sigwinch(signum, frame):
|
|
193
|
-
resize_pty()
|
|
194
|
-
|
|
195
|
-
old_sigwinch_handler = signal.signal(signal.SIGWINCH, handle_sigwinch)
|
|
196
|
-
|
|
197
|
-
# Save original terminal settings
|
|
198
|
-
old_tty = termios.tcgetattr(sys.stdin)
|
|
199
|
-
|
|
200
|
-
try:
|
|
201
|
-
# Set TERM environment variable to enable colors
|
|
202
|
-
env = os.environ.copy()
|
|
203
|
-
env["TERM"] = os.environ.get("TERM", "xterm-256color")
|
|
204
|
-
|
|
205
|
-
process = subprocess.Popen([lldb_command], stdin=slave, stdout=slave, stderr=slave, env=env)
|
|
206
|
-
os.close(slave)
|
|
207
|
-
|
|
208
|
-
# Put terminal in raw mode for proper interaction
|
|
209
|
-
tty.setraw(sys.stdin.fileno())
|
|
210
|
-
# Send all commands through stdin
|
|
211
|
-
for command in commands:
|
|
212
|
-
os.write(master, (command + "\n").encode())
|
|
213
|
-
|
|
214
|
-
# Now redirect stdin from the terminal to lldb so user can interact
|
|
215
|
-
while True:
|
|
216
|
-
rlist, _, _ = select_module.select([sys.stdin, master], [], [])
|
|
217
|
-
|
|
218
|
-
if sys.stdin in rlist:
|
|
219
|
-
# User typed something
|
|
220
|
-
data = os.read(sys.stdin.fileno(), 1024)
|
|
221
|
-
if not data:
|
|
222
|
-
break
|
|
223
|
-
os.write(master, data)
|
|
224
|
-
|
|
225
|
-
if master in rlist:
|
|
226
|
-
# lldb has output
|
|
227
|
-
try:
|
|
228
|
-
data = os.read(master, 1024)
|
|
229
|
-
if not data:
|
|
230
|
-
break
|
|
231
|
-
os.write(sys.stdout.fileno(), data)
|
|
232
|
-
except OSError:
|
|
233
|
-
break
|
|
234
|
-
except (KeyboardInterrupt, OSError):
|
|
235
|
-
pass
|
|
236
|
-
finally:
|
|
237
|
-
# Restore terminal settings
|
|
238
|
-
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
|
|
239
|
-
# Restore original SIGWINCH handler
|
|
240
|
-
signal.signal(signal.SIGWINCH, old_sigwinch_handler)
|
|
241
|
-
os.close(master)
|
|
242
|
-
if process is not None:
|
|
243
|
-
process.terminate()
|
|
244
|
-
process.wait()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|