|
1 | 1 | // Jackson Coxson |
2 | 2 |
|
3 | 3 | use clap::{Arg, Command}; |
| 4 | +use idevice::services::lockdown::LockdownClient; |
4 | 5 | use idevice::{IdeviceService, RsdService, core_device_proxy::CoreDeviceProxy, rsd::RsdHandshake}; |
5 | 6 |
|
6 | 7 | mod common; |
@@ -71,29 +72,70 @@ async fn main() { |
71 | 72 | } |
72 | 73 | }; |
73 | 74 |
|
74 | | - let proxy = CoreDeviceProxy::connect(&*provider) |
| 75 | + let mut rs_client_opt: Option< |
| 76 | + idevice::dvt::remote_server::RemoteServerClient<Box<dyn idevice::ReadWrite>>, |
| 77 | + > = None; |
| 78 | + |
| 79 | + if let Ok(proxy) = CoreDeviceProxy::connect(&*provider).await { |
| 80 | + let rsd_port = proxy.handshake.server_rsd_port; |
| 81 | + let adapter = proxy.create_software_tunnel().expect("no software tunnel"); |
| 82 | + let mut adapter = adapter.to_async_handle(); |
| 83 | + let stream = adapter.connect(rsd_port).await.expect("no RSD connect"); |
| 84 | + |
| 85 | + // Make the connection to RemoteXPC (iOS 17+) |
| 86 | + let mut handshake = RsdHandshake::new(stream).await.unwrap(); |
| 87 | + let mut rs_client = idevice::dvt::remote_server::RemoteServerClient::connect_rsd( |
| 88 | + &mut adapter, |
| 89 | + &mut handshake, |
| 90 | + ) |
75 | 91 | .await |
76 | | - .expect("no core proxy"); |
77 | | - let rsd_port = proxy.handshake.server_rsd_port; |
| 92 | + .expect("no connect"); |
| 93 | + rs_client.read_message(0).await.expect("no read??"); |
| 94 | + rs_client_opt = Some(rs_client); |
| 95 | + } |
78 | 96 |
|
79 | | - let adapter = proxy.create_software_tunnel().expect("no software tunnel"); |
80 | | - let mut adapter = adapter.to_async_handle(); |
81 | | - let stream = adapter.connect(rsd_port).await.expect("no RSD connect"); |
| 97 | + let mut rs_client = if let Some(c) = rs_client_opt { |
| 98 | + c |
| 99 | + } else { |
| 100 | + // Read iOS version to decide whether we can fallback to remoteserver |
| 101 | + let mut lockdown = LockdownClient::connect(&*provider) |
| 102 | + .await |
| 103 | + .expect("lockdown connect failed"); |
| 104 | + lockdown |
| 105 | + .start_session(&provider.get_pairing_file().await.expect("pairing file")) |
| 106 | + .await |
| 107 | + .expect("lockdown start_session failed"); |
| 108 | + let pv = lockdown |
| 109 | + .get_value(Some("ProductVersion"), None) |
| 110 | + .await |
| 111 | + .ok() |
| 112 | + .and_then(|v| v.as_string().map(|s| s.to_string())) |
| 113 | + .unwrap_or_default(); |
| 114 | + let major: u32 = pv |
| 115 | + .split('.') |
| 116 | + .next() |
| 117 | + .and_then(|s| s.parse().ok()) |
| 118 | + .unwrap_or(0); |
82 | 119 |
|
83 | | - // Make the connection to RemoteXPC |
84 | | - let mut handshake = RsdHandshake::new(stream).await.unwrap(); |
| 120 | + if major >= 17 { |
| 121 | + // iOS 17+ with no CoreDeviceProxy: do not attempt remoteserver (would return InvalidService) |
| 122 | + panic!("iOS {pv} detected and CoreDeviceProxy unavailable. RemoteXPC tunnel required."); |
| 123 | + } |
85 | 124 |
|
86 | | - let mut rs_client = |
87 | | - idevice::dvt::remote_server::RemoteServerClient::connect_rsd(&mut adapter, &mut handshake) |
| 125 | + // iOS 16 and earlier: fallback to Lockdown remoteserver (or DVTSecureSocketProxy) |
| 126 | + idevice::dvt::remote_server::RemoteServerClient::connect(&*provider) |
88 | 127 | .await |
89 | | - .expect("no connect"); |
| 128 | + .expect("failed to connect to Instruments Remote Server over Lockdown (iOS16-). Ensure Developer Disk Image is mounted.") |
| 129 | + }; |
| 130 | + |
| 131 | + // Note: On both transports, protocol requires reading the initial message on root channel (0) |
90 | 132 | rs_client.read_message(0).await.expect("no read??"); |
91 | 133 | let mut pc_client = idevice::dvt::process_control::ProcessControlClient::new(&mut rs_client) |
92 | 134 | .await |
93 | 135 | .unwrap(); |
94 | 136 |
|
95 | 137 | let pid = pc_client |
96 | | - .launch_app(bundle_id, None, None, true, false) |
| 138 | + .launch_app(bundle_id, None, None, false, false) |
97 | 139 | .await |
98 | 140 | .expect("no launch??"); |
99 | 141 | pc_client |
|
0 commit comments