pymobiledevice3 5.0.4__py3-none-any.whl → 7.0.6__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.
- misc/understanding_idevice_protocol_layers.md +10 -5
- pymobiledevice3/__main__.py +171 -46
- pymobiledevice3/_version.py +2 -2
- pymobiledevice3/bonjour.py +22 -21
- pymobiledevice3/cli/activation.py +24 -22
- pymobiledevice3/cli/afc.py +49 -41
- pymobiledevice3/cli/amfi.py +13 -18
- pymobiledevice3/cli/apps.py +71 -65
- pymobiledevice3/cli/backup.py +134 -93
- pymobiledevice3/cli/bonjour.py +31 -29
- pymobiledevice3/cli/cli_common.py +175 -232
- pymobiledevice3/cli/companion_proxy.py +12 -12
- pymobiledevice3/cli/crash.py +95 -52
- pymobiledevice3/cli/developer/__init__.py +62 -0
- pymobiledevice3/cli/developer/accessibility/__init__.py +65 -0
- pymobiledevice3/cli/developer/accessibility/settings.py +43 -0
- pymobiledevice3/cli/developer/arbitration.py +50 -0
- pymobiledevice3/cli/developer/condition.py +33 -0
- pymobiledevice3/cli/developer/core_device.py +294 -0
- pymobiledevice3/cli/developer/debugserver.py +244 -0
- pymobiledevice3/cli/developer/dvt/__init__.py +438 -0
- pymobiledevice3/cli/developer/dvt/core_profile_session.py +295 -0
- pymobiledevice3/cli/developer/dvt/simulate_location.py +56 -0
- pymobiledevice3/cli/developer/dvt/sysmon/__init__.py +69 -0
- pymobiledevice3/cli/developer/dvt/sysmon/process.py +188 -0
- pymobiledevice3/cli/developer/fetch_symbols.py +108 -0
- pymobiledevice3/cli/developer/simulate_location.py +51 -0
- pymobiledevice3/cli/diagnostics/__init__.py +75 -0
- pymobiledevice3/cli/diagnostics/battery.py +47 -0
- pymobiledevice3/cli/idam.py +42 -0
- pymobiledevice3/cli/lockdown.py +70 -75
- pymobiledevice3/cli/mounter.py +99 -57
- pymobiledevice3/cli/notification.py +38 -26
- pymobiledevice3/cli/pcap.py +36 -20
- pymobiledevice3/cli/power_assertion.py +15 -16
- pymobiledevice3/cli/processes.py +11 -17
- pymobiledevice3/cli/profile.py +120 -75
- pymobiledevice3/cli/provision.py +27 -26
- pymobiledevice3/cli/remote.py +109 -100
- pymobiledevice3/cli/restore.py +134 -129
- pymobiledevice3/cli/springboard.py +50 -50
- pymobiledevice3/cli/syslog.py +145 -65
- pymobiledevice3/cli/usbmux.py +66 -27
- pymobiledevice3/cli/version.py +2 -5
- pymobiledevice3/cli/webinspector.py +232 -156
- pymobiledevice3/exceptions.py +6 -2
- pymobiledevice3/lockdown.py +5 -1
- pymobiledevice3/lockdown_service_provider.py +5 -0
- pymobiledevice3/remote/remote_service_discovery.py +18 -10
- pymobiledevice3/restore/device.py +28 -4
- pymobiledevice3/restore/restore.py +2 -2
- pymobiledevice3/service_connection.py +15 -12
- pymobiledevice3/services/afc.py +731 -220
- pymobiledevice3/services/device_link.py +45 -31
- pymobiledevice3/services/idam.py +20 -0
- pymobiledevice3/services/lockdown_service.py +12 -9
- pymobiledevice3/services/mobile_config.py +1 -0
- pymobiledevice3/services/mobilebackup2.py +6 -3
- pymobiledevice3/services/os_trace.py +97 -55
- pymobiledevice3/services/remote_fetch_symbols.py +13 -8
- pymobiledevice3/services/screenshot.py +2 -2
- pymobiledevice3/services/web_protocol/alert.py +8 -8
- pymobiledevice3/services/web_protocol/automation_session.py +87 -79
- pymobiledevice3/services/web_protocol/cdp_screencast.py +2 -1
- pymobiledevice3/services/web_protocol/driver.py +71 -70
- pymobiledevice3/services/web_protocol/element.py +58 -56
- pymobiledevice3/services/web_protocol/selenium_api.py +47 -47
- pymobiledevice3/services/web_protocol/session_protocol.py +3 -2
- pymobiledevice3/services/web_protocol/switch_to.py +23 -19
- pymobiledevice3/services/webinspector.py +42 -67
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/METADATA +5 -3
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/RECORD +76 -61
- pymobiledevice3/cli/completions.py +0 -50
- pymobiledevice3/cli/developer.py +0 -1539
- pymobiledevice3/cli/diagnostics.py +0 -110
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/WHEEL +0 -0
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/entry_points.txt +0 -0
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/licenses/LICENSE +0 -0
- {pymobiledevice3-5.0.4.dist-info → pymobiledevice3-7.0.6.dist-info}/top_level.txt +0 -0
pymobiledevice3/cli/mounter.py
CHANGED
|
@@ -2,18 +2,19 @@ import asyncio
|
|
|
2
2
|
import logging
|
|
3
3
|
from functools import update_wrapper
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
from typing import Annotated, Optional
|
|
5
6
|
from urllib.error import URLError
|
|
6
7
|
|
|
7
|
-
import
|
|
8
|
+
import typer
|
|
9
|
+
from typer_injector import InjectingTyper
|
|
8
10
|
|
|
9
|
-
from pymobiledevice3.cli.cli_common import
|
|
11
|
+
from pymobiledevice3.cli.cli_common import ServiceProviderDep, print_json
|
|
10
12
|
from pymobiledevice3.exceptions import (
|
|
11
13
|
AlreadyMountedError,
|
|
12
14
|
DeveloperDiskImageNotFoundError,
|
|
13
15
|
NotMountedError,
|
|
14
16
|
UnsupportedCommandError,
|
|
15
17
|
)
|
|
16
|
-
from pymobiledevice3.lockdown import LockdownClient
|
|
17
18
|
from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider
|
|
18
19
|
from pymobiledevice3.services.mobile_image_mounter import (
|
|
19
20
|
DeveloperDiskImageMounter,
|
|
@@ -37,19 +38,15 @@ def catch_errors(func):
|
|
|
37
38
|
return update_wrapper(catch_function, func)
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@cli.group()
|
|
46
|
-
def mounter() -> None:
|
|
47
|
-
"""Mount/Umount DeveloperDiskImage or query related info"""
|
|
48
|
-
pass
|
|
41
|
+
cli = InjectingTyper(
|
|
42
|
+
name="mounter",
|
|
43
|
+
help="Mount/Umount DeveloperDiskImage or query related info",
|
|
44
|
+
no_args_is_help=True,
|
|
45
|
+
)
|
|
49
46
|
|
|
50
47
|
|
|
51
|
-
@
|
|
52
|
-
def mounter_list(service_provider:
|
|
48
|
+
@cli.command("list")
|
|
49
|
+
def mounter_list(service_provider: ServiceProviderDep) -> None:
|
|
53
50
|
"""list all mounted images"""
|
|
54
51
|
output = []
|
|
55
52
|
|
|
@@ -63,9 +60,8 @@ def mounter_list(service_provider: LockdownClient):
|
|
|
63
60
|
print_json(output)
|
|
64
61
|
|
|
65
62
|
|
|
66
|
-
@
|
|
67
|
-
|
|
68
|
-
def mounter_lookup(service_provider: LockdownClient, image_type):
|
|
63
|
+
@cli.command("lookup")
|
|
64
|
+
def mounter_lookup(service_provider: ServiceProviderDep, image_type: str) -> None:
|
|
69
65
|
"""lookup mounter image type"""
|
|
70
66
|
try:
|
|
71
67
|
signature = MobileImageMounterService(lockdown=service_provider).lookup_image(image_type)
|
|
@@ -74,9 +70,9 @@ def mounter_lookup(service_provider: LockdownClient, image_type):
|
|
|
74
70
|
logger.error(f"Disk image of type: {image_type} is not mounted")
|
|
75
71
|
|
|
76
72
|
|
|
77
|
-
@
|
|
73
|
+
@cli.command("umount-developer")
|
|
78
74
|
@catch_errors
|
|
79
|
-
def mounter_umount_developer(service_provider:
|
|
75
|
+
def mounter_umount_developer(service_provider: ServiceProviderDep) -> None:
|
|
80
76
|
"""unmount Developer image"""
|
|
81
77
|
try:
|
|
82
78
|
DeveloperDiskImageMounter(lockdown=service_provider).umount()
|
|
@@ -85,9 +81,9 @@ def mounter_umount_developer(service_provider: LockdownClient):
|
|
|
85
81
|
logger.error("Developer image isn't currently mounted")
|
|
86
82
|
|
|
87
83
|
|
|
88
|
-
@
|
|
84
|
+
@cli.command("umount-personalized")
|
|
89
85
|
@catch_errors
|
|
90
|
-
def mounter_umount_personalized(service_provider:
|
|
86
|
+
def mounter_umount_personalized(service_provider: ServiceProviderDep) -> None:
|
|
91
87
|
"""unmount Personalized image"""
|
|
92
88
|
try:
|
|
93
89
|
PersonalizedImageMounter(lockdown=service_provider).umount()
|
|
@@ -96,13 +92,29 @@ def mounter_umount_personalized(service_provider: LockdownClient):
|
|
|
96
92
|
logger.error("Personalized image isn't currently mounted")
|
|
97
93
|
|
|
98
94
|
|
|
99
|
-
@
|
|
100
|
-
@click.argument("image", type=click.Path(exists=True, file_okay=True, dir_okay=False))
|
|
101
|
-
@click.argument("signature", type=click.Path(exists=True, file_okay=True, dir_okay=False))
|
|
95
|
+
@cli.command("mount-developer")
|
|
102
96
|
@catch_errors
|
|
103
|
-
def mounter_mount_developer(
|
|
97
|
+
def mounter_mount_developer(
|
|
98
|
+
service_provider: ServiceProviderDep,
|
|
99
|
+
image: Annotated[
|
|
100
|
+
Path,
|
|
101
|
+
typer.Argument(
|
|
102
|
+
exists=True,
|
|
103
|
+
file_okay=True,
|
|
104
|
+
dir_okay=False,
|
|
105
|
+
),
|
|
106
|
+
],
|
|
107
|
+
signature: Annotated[
|
|
108
|
+
Path,
|
|
109
|
+
typer.Argument(
|
|
110
|
+
exists=True,
|
|
111
|
+
file_okay=True,
|
|
112
|
+
dir_okay=False,
|
|
113
|
+
),
|
|
114
|
+
],
|
|
115
|
+
) -> None:
|
|
104
116
|
"""mount developer image"""
|
|
105
|
-
DeveloperDiskImageMounter(lockdown=service_provider).mount(
|
|
117
|
+
DeveloperDiskImageMounter(lockdown=service_provider).mount(image, signature)
|
|
106
118
|
logger.info("Developer image mounted successfully")
|
|
107
119
|
|
|
108
120
|
|
|
@@ -115,16 +127,39 @@ async def mounter_mount_personalized_task(
|
|
|
115
127
|
logger.info("Personalized image mounted successfully")
|
|
116
128
|
|
|
117
129
|
|
|
118
|
-
@
|
|
119
|
-
@click.argument("image", type=click.Path(exists=True, file_okay=True, dir_okay=False))
|
|
120
|
-
@click.argument("trust-cache", type=click.Path(exists=True, file_okay=True, dir_okay=False))
|
|
121
|
-
@click.argument("build-manifest", type=click.Path(exists=True, file_okay=True, dir_okay=False))
|
|
130
|
+
@cli.command("mount-personalized")
|
|
122
131
|
@catch_errors
|
|
123
132
|
def mounter_mount_personalized(
|
|
124
|
-
service_provider:
|
|
133
|
+
service_provider: ServiceProviderDep,
|
|
134
|
+
image: Annotated[
|
|
135
|
+
Path,
|
|
136
|
+
typer.Argument(
|
|
137
|
+
exists=True,
|
|
138
|
+
file_okay=True,
|
|
139
|
+
dir_okay=False,
|
|
140
|
+
),
|
|
141
|
+
],
|
|
142
|
+
trust_cache: Annotated[
|
|
143
|
+
Path,
|
|
144
|
+
typer.Argument(
|
|
145
|
+
exists=True,
|
|
146
|
+
file_okay=True,
|
|
147
|
+
dir_okay=False,
|
|
148
|
+
),
|
|
149
|
+
],
|
|
150
|
+
build_manifest: Annotated[
|
|
151
|
+
Path,
|
|
152
|
+
typer.Argument(
|
|
153
|
+
exists=True,
|
|
154
|
+
file_okay=True,
|
|
155
|
+
dir_okay=False,
|
|
156
|
+
),
|
|
157
|
+
],
|
|
125
158
|
) -> None:
|
|
126
159
|
"""mount personalized image"""
|
|
127
|
-
asyncio.run(
|
|
160
|
+
asyncio.run(
|
|
161
|
+
mounter_mount_personalized_task(service_provider, str(image), str(trust_cache), str(build_manifest)), debug=True
|
|
162
|
+
)
|
|
128
163
|
|
|
129
164
|
|
|
130
165
|
async def mounter_auto_mount_task(service_provider: LockdownServiceProvider, xcode: str, version: str) -> None:
|
|
@@ -144,42 +179,49 @@ async def mounter_auto_mount_task(service_provider: LockdownServiceProvider, xco
|
|
|
144
179
|
)
|
|
145
180
|
|
|
146
181
|
|
|
147
|
-
@
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
182
|
+
@cli.command("auto-mount")
|
|
183
|
+
def mounter_auto_mount(
|
|
184
|
+
service_provider: ServiceProviderDep,
|
|
185
|
+
xcode: Annotated[
|
|
186
|
+
Optional[Path],
|
|
187
|
+
typer.Option(
|
|
188
|
+
"--xcode",
|
|
189
|
+
"-x",
|
|
190
|
+
exists=True,
|
|
191
|
+
file_okay=True,
|
|
192
|
+
dir_okay=False,
|
|
193
|
+
help="Xcode application path used to figure out automatically the DeveloperDiskImage path",
|
|
194
|
+
),
|
|
195
|
+
] = None,
|
|
196
|
+
version: Annotated[
|
|
197
|
+
Optional[str],
|
|
198
|
+
typer.Option(help="Use a different DeveloperDiskImage version from the one retrieved by lockdownconnection"),
|
|
199
|
+
] = None,
|
|
200
|
+
) -> None:
|
|
158
201
|
"""auto-detect correct DeveloperDiskImage and mount it"""
|
|
159
|
-
asyncio.run(mounter_auto_mount_task(service_provider, xcode, version), debug=True)
|
|
202
|
+
asyncio.run(mounter_auto_mount_task(service_provider, str(xcode), version), debug=True)
|
|
160
203
|
|
|
161
204
|
|
|
162
|
-
@
|
|
163
|
-
def mounter_query_developer_mode_status(service_provider:
|
|
205
|
+
@cli.command("query-developer-mode-status")
|
|
206
|
+
def mounter_query_developer_mode_status(service_provider: ServiceProviderDep) -> None:
|
|
164
207
|
"""Query developer mode status"""
|
|
165
208
|
print_json(MobileImageMounterService(lockdown=service_provider).query_developer_mode_status())
|
|
166
209
|
|
|
167
210
|
|
|
168
|
-
@
|
|
169
|
-
|
|
170
|
-
def mounter_query_nonce(service_provider: LockdownClient, image_type: str):
|
|
211
|
+
@cli.command("query-nonce")
|
|
212
|
+
def mounter_query_nonce(service_provider: ServiceProviderDep, image_type: Annotated[str, typer.Option()]) -> None:
|
|
171
213
|
"""Query nonce"""
|
|
172
214
|
print_json(MobileImageMounterService(lockdown=service_provider).query_nonce(image_type))
|
|
173
215
|
|
|
174
216
|
|
|
175
|
-
@
|
|
176
|
-
def mounter_query_personalization_identifiers(service_provider:
|
|
217
|
+
@cli.command("query-personalization-identifiers")
|
|
218
|
+
def mounter_query_personalization_identifiers(service_provider: ServiceProviderDep) -> None:
|
|
177
219
|
"""Query personalization identifiers"""
|
|
178
220
|
print_json(MobileImageMounterService(lockdown=service_provider).query_personalization_identifiers())
|
|
179
221
|
|
|
180
222
|
|
|
181
|
-
@
|
|
182
|
-
def mounter_query_personalization_manifest(service_provider:
|
|
223
|
+
@cli.command("query-personalization-manifest")
|
|
224
|
+
def mounter_query_personalization_manifest(service_provider: ServiceProviderDep) -> None:
|
|
183
225
|
"""Query personalization manifest"""
|
|
184
226
|
result = []
|
|
185
227
|
mounter = MobileImageMounterService(lockdown=service_provider)
|
|
@@ -188,12 +230,12 @@ def mounter_query_personalization_manifest(service_provider: LockdownClient):
|
|
|
188
230
|
print_json(result)
|
|
189
231
|
|
|
190
232
|
|
|
191
|
-
@
|
|
192
|
-
def mounter_roll_personalization_nonce(service_provider:
|
|
233
|
+
@cli.command("roll-personalization-nonce")
|
|
234
|
+
def mounter_roll_personalization_nonce(service_provider: ServiceProviderDep) -> None:
|
|
193
235
|
MobileImageMounterService(lockdown=service_provider).roll_personalization_nonce()
|
|
194
236
|
|
|
195
237
|
|
|
196
|
-
@
|
|
197
|
-
def mounter_roll_cryptex_nonce(service_provider:
|
|
238
|
+
@cli.command("roll-cryptex-nonce")
|
|
239
|
+
def mounter_roll_cryptex_nonce(service_provider: ServiceProviderDep) -> None:
|
|
198
240
|
"""Roll cryptex nonce (will reboot)"""
|
|
199
241
|
MobileImageMounterService(lockdown=service_provider).roll_cryptex_nonce()
|
|
@@ -1,41 +1,48 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from typing import Annotated
|
|
2
3
|
|
|
3
|
-
import
|
|
4
|
+
import typer
|
|
5
|
+
from typer_injector import InjectingTyper
|
|
4
6
|
|
|
5
|
-
from pymobiledevice3.cli.cli_common import
|
|
6
|
-
from pymobiledevice3.lockdown import LockdownClient
|
|
7
|
+
from pymobiledevice3.cli.cli_common import ServiceProviderDep
|
|
7
8
|
from pymobiledevice3.resources.firmware_notifications import get_notifications
|
|
8
9
|
from pymobiledevice3.services.notification_proxy import NotificationProxyService
|
|
9
10
|
|
|
10
11
|
logger = logging.getLogger(__name__)
|
|
11
12
|
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
cli = InjectingTyper(
|
|
15
|
+
name="notifications",
|
|
16
|
+
help="Post or observe Darwin notifications via notification_proxy.",
|
|
17
|
+
no_args_is_help=True,
|
|
18
|
+
)
|
|
16
19
|
|
|
17
20
|
|
|
18
|
-
@cli.
|
|
19
|
-
def
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"""API for notify_post()."""
|
|
21
|
+
@cli.command()
|
|
22
|
+
def post(
|
|
23
|
+
service_provider: ServiceProviderDep,
|
|
24
|
+
names: list[str],
|
|
25
|
+
insecure: Annotated[
|
|
26
|
+
bool,
|
|
27
|
+
typer.Option(help="Use the insecure relay meant for untrusted clients instead of the trusted channel."),
|
|
28
|
+
],
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Post one or more Darwin notifications (notify_post)."""
|
|
29
31
|
service = NotificationProxyService(lockdown=service_provider, insecure=insecure)
|
|
30
32
|
for name in names:
|
|
31
33
|
service.notify_post(name)
|
|
32
34
|
|
|
33
35
|
|
|
34
|
-
@
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
@cli.command()
|
|
37
|
+
def observe(
|
|
38
|
+
service_provider: ServiceProviderDep,
|
|
39
|
+
names: list[str],
|
|
40
|
+
insecure: Annotated[
|
|
41
|
+
bool,
|
|
42
|
+
typer.Option(help="Use the insecure relay meant for untrusted clients instead of the trusted channel."),
|
|
43
|
+
],
|
|
44
|
+
) -> None:
|
|
45
|
+
"""Subscribe and stream notifications (notify_register_dispatch)."""
|
|
39
46
|
service = NotificationProxyService(lockdown=service_provider, insecure=insecure)
|
|
40
47
|
for name in names:
|
|
41
48
|
service.notify_register_dispatch(name)
|
|
@@ -44,10 +51,15 @@ def observe(service_provider: LockdownClient, names, insecure):
|
|
|
44
51
|
logger.info(event)
|
|
45
52
|
|
|
46
53
|
|
|
47
|
-
@
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
@cli.command("observe-all")
|
|
55
|
+
def observe_all(
|
|
56
|
+
service_provider: ServiceProviderDep,
|
|
57
|
+
insecure: Annotated[
|
|
58
|
+
bool,
|
|
59
|
+
typer.Option(help="Use the insecure relay meant for untrusted clients instead of the trusted channel."),
|
|
60
|
+
],
|
|
61
|
+
) -> None:
|
|
62
|
+
"""Subscribe to all known firmware notifications and stream events."""
|
|
51
63
|
service = NotificationProxyService(lockdown=service_provider, insecure=insecure)
|
|
52
64
|
for notification in get_notifications():
|
|
53
65
|
service.notify_register_dispatch(notification)
|
pymobiledevice3/cli/pcap.py
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
-
from
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Annotated, Optional
|
|
3
4
|
|
|
4
|
-
import
|
|
5
|
+
import typer
|
|
5
6
|
from pygments import formatters, highlight, lexers
|
|
7
|
+
from typer_injector import InjectingTyper
|
|
6
8
|
|
|
7
|
-
from pymobiledevice3.cli.cli_common import
|
|
8
|
-
from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider
|
|
9
|
+
from pymobiledevice3.cli.cli_common import ServiceProviderDep, print_hex, user_requested_colored_output
|
|
9
10
|
from pymobiledevice3.services.pcapd import PcapdService
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
cli = InjectingTyper(
|
|
13
|
+
name="pcap",
|
|
14
|
+
help="Sniff device traffic via pcapd and optionally save to a .pcap file.",
|
|
15
|
+
no_args_is_help=True,
|
|
16
|
+
)
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def print_packet_header(packet, color: bool) -> None:
|
|
@@ -37,25 +39,39 @@ def print_packet(packet, color: Optional[bool] = None):
|
|
|
37
39
|
return packet
|
|
38
40
|
|
|
39
41
|
|
|
40
|
-
@cli.command(
|
|
41
|
-
@click.argument("out", type=click.File("wb"), required=False)
|
|
42
|
-
@click.option("-c", "--count", type=click.INT, default=-1, help="Number of packets to sniff. Omit to endless sniff.")
|
|
43
|
-
@click.option("--process", default=None, help="Process to filter. Omit for all.")
|
|
44
|
-
@click.option("-i", "--interface", default=None, help="Interface name to filter. Omit for all.")
|
|
42
|
+
@cli.command()
|
|
45
43
|
def pcap(
|
|
46
|
-
service_provider:
|
|
47
|
-
out: Optional[
|
|
48
|
-
count:
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
service_provider: ServiceProviderDep,
|
|
45
|
+
out: Optional[Path] = None,
|
|
46
|
+
count: Annotated[
|
|
47
|
+
int,
|
|
48
|
+
typer.Option(
|
|
49
|
+
"--count",
|
|
50
|
+
"-c",
|
|
51
|
+
help="Number of packets to sniff. Omit to endless sniff.",
|
|
52
|
+
),
|
|
53
|
+
] = -1,
|
|
54
|
+
process: Annotated[
|
|
55
|
+
Optional[str],
|
|
56
|
+
typer.Option(help="Process to filter. Omit for all."),
|
|
57
|
+
] = None,
|
|
58
|
+
interface: Annotated[
|
|
59
|
+
Optional[str],
|
|
60
|
+
typer.Option(
|
|
61
|
+
"--interface",
|
|
62
|
+
"-i",
|
|
63
|
+
help="Interface name to filter. Omit for all.",
|
|
64
|
+
),
|
|
65
|
+
] = None,
|
|
51
66
|
) -> None:
|
|
52
|
-
"""Sniff device traffic"""
|
|
67
|
+
"""Sniff device traffic."""
|
|
53
68
|
service = PcapdService(lockdown=service_provider)
|
|
54
69
|
packets_generator = service.watch(packets_count=count, process=process, interface_name=interface)
|
|
55
70
|
|
|
56
71
|
if out is not None:
|
|
57
72
|
packets_generator_with_print = (print_packet(p) for p in packets_generator)
|
|
58
|
-
|
|
73
|
+
with out.open("wb") as out_file:
|
|
74
|
+
service.write_to_pcap(out_file, packets_generator_with_print)
|
|
59
75
|
return
|
|
60
76
|
|
|
61
77
|
for packet in packets_generator:
|
|
@@ -1,26 +1,25 @@
|
|
|
1
1
|
import time
|
|
2
|
+
from typing import Literal, Optional
|
|
2
3
|
|
|
3
|
-
import
|
|
4
|
+
from typer_injector import InjectingTyper
|
|
4
5
|
|
|
5
|
-
from pymobiledevice3.cli.cli_common import
|
|
6
|
-
from pymobiledevice3.lockdown_service_provider import LockdownServiceProvider
|
|
6
|
+
from pymobiledevice3.cli.cli_common import ServiceProviderDep
|
|
7
7
|
from pymobiledevice3.services.power_assertion import PowerAssertionService
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
cli = InjectingTyper(
|
|
10
|
+
name="power-assertion",
|
|
11
|
+
no_args_is_help=True,
|
|
12
|
+
)
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
@cli.command("power-assertion"
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def power_assertion(service_provider: LockdownServiceProvider, assertion_type, name, timeout, details) -> None:
|
|
15
|
+
@cli.command("power-assertion")
|
|
16
|
+
def power_assertion(
|
|
17
|
+
service_provider: ServiceProviderDep,
|
|
18
|
+
assertion_type: Literal["AMDPowerAssertionTypeWirelessSync", "PreventUserIdleSystemSleep", "PreventSystemSleep"],
|
|
19
|
+
name: str,
|
|
20
|
+
timeout: int,
|
|
21
|
+
details: Optional[str] = None,
|
|
22
|
+
) -> None:
|
|
24
23
|
"""Create a power assertion"""
|
|
25
24
|
with PowerAssertionService(service_provider).create_power_assertion(assertion_type, name, timeout, details):
|
|
26
25
|
print("> Hit Ctrl+C to exit")
|
pymobiledevice3/cli/processes.py
CHANGED
|
@@ -1,34 +1,28 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
from typer_injector import InjectingTyper
|
|
4
4
|
|
|
5
|
-
from pymobiledevice3.cli.cli_common import
|
|
6
|
-
from pymobiledevice3.lockdown import LockdownClient
|
|
5
|
+
from pymobiledevice3.cli.cli_common import ServiceProviderDep, print_json
|
|
7
6
|
from pymobiledevice3.services.os_trace import OsTraceService
|
|
8
7
|
|
|
9
8
|
logger = logging.getLogger(__name__)
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
cli = InjectingTyper(
|
|
12
|
+
name="processes",
|
|
13
|
+
help="View process list using diagnosticsd API",
|
|
14
|
+
no_args_is_help=True,
|
|
15
|
+
)
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
@cli.
|
|
18
|
-
def
|
|
19
|
-
"""View process list using diagnosticsd API"""
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@processes.command("ps", cls=Command)
|
|
24
|
-
def processes_ps(service_provider: LockdownClient):
|
|
18
|
+
@cli.command("ps")
|
|
19
|
+
def processes_ps(service_provider: ServiceProviderDep) -> None:
|
|
25
20
|
"""show process list"""
|
|
26
21
|
print_json(OsTraceService(lockdown=service_provider).get_pid_list().get("Payload"))
|
|
27
22
|
|
|
28
23
|
|
|
29
|
-
@
|
|
30
|
-
|
|
31
|
-
def processes_pgrep(service_provider: LockdownClient, expression):
|
|
24
|
+
@cli.command("pgrep")
|
|
25
|
+
def processes_pgrep(service_provider: ServiceProviderDep, expression: str) -> None:
|
|
32
26
|
"""try to match processes pid by given expression (like pgrep)"""
|
|
33
27
|
processes_list = OsTraceService(lockdown=service_provider).get_pid_list().get("Payload")
|
|
34
28
|
for pid, process_info in processes_list.items():
|