mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Partial diagnostics relay implementation
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1086,7 +1086,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idevice"
|
name = "idevice"
|
||||||
version = "0.1.36"
|
version = "0.1.37"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
name = "idevice"
|
name = "idevice"
|
||||||
description = "A Rust library to interact with services on iOS devices."
|
description = "A Rust library to interact with services on iOS devices."
|
||||||
authors = ["Jackson Coxson"]
|
authors = ["Jackson Coxson"]
|
||||||
version = "0.1.36"
|
version = "0.1.37"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
documentation = "https://docs.rs/idevice"
|
documentation = "https://docs.rs/idevice"
|
||||||
@@ -62,6 +62,7 @@ core_device = ["xpc", "dep:uuid"]
|
|||||||
core_device_proxy = ["dep:serde_json", "dep:json", "dep:byteorder"]
|
core_device_proxy = ["dep:serde_json", "dep:json", "dep:byteorder"]
|
||||||
crashreportcopymobile = ["afc"]
|
crashreportcopymobile = ["afc"]
|
||||||
debug_proxy = []
|
debug_proxy = []
|
||||||
|
diagnostics_relay = []
|
||||||
dvt = ["dep:byteorder", "dep:ns-keyed-archive"]
|
dvt = ["dep:byteorder", "dep:ns-keyed-archive"]
|
||||||
heartbeat = ["tokio/macros", "tokio/time"]
|
heartbeat = ["tokio/macros", "tokio/time"]
|
||||||
house_arrest = ["afc"]
|
house_arrest = ["afc"]
|
||||||
@@ -88,6 +89,7 @@ full = [
|
|||||||
"core_device_proxy",
|
"core_device_proxy",
|
||||||
"crashreportcopymobile",
|
"crashreportcopymobile",
|
||||||
"debug_proxy",
|
"debug_proxy",
|
||||||
|
"diagnostics_relay",
|
||||||
"dvt",
|
"dvt",
|
||||||
"heartbeat",
|
"heartbeat",
|
||||||
"house_arrest",
|
"house_arrest",
|
||||||
|
|||||||
113
idevice/src/services/diagnostics_relay.rs
Normal file
113
idevice/src/services/diagnostics_relay.rs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
//! Diagnostics Relay
|
||||||
|
|
||||||
|
use crate::{lockdown::LockdownClient, obf, Idevice, IdeviceError, IdeviceService};
|
||||||
|
|
||||||
|
/// Client for interacting with the Diagnostics Relay
|
||||||
|
pub struct DiagnosticsRelayClient {
|
||||||
|
/// The underlying device connection with established service
|
||||||
|
pub idevice: Idevice,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdeviceService for DiagnosticsRelayClient {
|
||||||
|
/// Returns the service name as registered with lockdownd
|
||||||
|
fn service_name() -> std::borrow::Cow<'static, str> {
|
||||||
|
obf!("com.apple.mobile.diagnostics_relay")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Establishes a connection to the service
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `provider` - Device connection provider
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// A connected `DiagnosticsRelayClient` instance
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// Returns `IdeviceError` if any step of the connection process fails
|
||||||
|
///
|
||||||
|
/// # Process
|
||||||
|
/// 1. Connects to lockdownd service
|
||||||
|
/// 2. Starts a lockdown session
|
||||||
|
/// 3. Requests the service port
|
||||||
|
/// 4. Establishes connection to the port
|
||||||
|
/// 5. Optionally starts TLS if required by service
|
||||||
|
async fn connect(
|
||||||
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
|
) -> Result<Self, IdeviceError> {
|
||||||
|
let mut lockdown = LockdownClient::connect(provider).await?;
|
||||||
|
lockdown
|
||||||
|
.start_session(&provider.get_pairing_file().await?)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
||||||
|
|
||||||
|
let mut idevice = provider.connect(port).await?;
|
||||||
|
if ssl {
|
||||||
|
idevice
|
||||||
|
.start_session(&provider.get_pairing_file().await?)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { idevice })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DiagnosticsRelayClient {
|
||||||
|
/// Creates a new client from an existing device connection
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `idevice` - Pre-established device connection
|
||||||
|
pub fn new(idevice: Idevice) -> Self {
|
||||||
|
Self { idevice }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Requests data from the IO registry
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// * `current_plane` - The plane to request the tree as
|
||||||
|
/// * `entry_name` - The entry to get
|
||||||
|
/// * `entry_class` - The class to filter by
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// A plist of the tree on success
|
||||||
|
pub async fn ioregistry(
|
||||||
|
&mut self,
|
||||||
|
current_plane: Option<impl Into<String>>,
|
||||||
|
entry_name: Option<impl Into<String>>,
|
||||||
|
entry_class: Option<impl Into<String>>,
|
||||||
|
) -> Result<Option<plist::Dictionary>, IdeviceError> {
|
||||||
|
let mut req = plist::Dictionary::new();
|
||||||
|
if let Some(plane) = current_plane {
|
||||||
|
let plane = plane.into();
|
||||||
|
req.insert("CurrentPlane".into(), plane.into());
|
||||||
|
}
|
||||||
|
if let Some(name) = entry_name {
|
||||||
|
let name = name.into();
|
||||||
|
req.insert("EntryName".into(), name.into());
|
||||||
|
}
|
||||||
|
if let Some(class) = entry_class {
|
||||||
|
let class = class.into();
|
||||||
|
req.insert("EntryClass".into(), class.into());
|
||||||
|
}
|
||||||
|
req.insert("Request".into(), "IORegistry".into());
|
||||||
|
self.idevice
|
||||||
|
.send_plist(plist::Value::Dictionary(req))
|
||||||
|
.await?;
|
||||||
|
let mut res = self.idevice.read_plist().await?;
|
||||||
|
|
||||||
|
match res.get("Status").and_then(|x| x.as_string()) {
|
||||||
|
Some("Success") => {}
|
||||||
|
_ => {
|
||||||
|
return Err(IdeviceError::UnexpectedResponse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = res
|
||||||
|
.remove("Diagnostics")
|
||||||
|
.and_then(|x| x.into_dictionary())
|
||||||
|
.and_then(|mut x| x.remove("IORegistry"))
|
||||||
|
.and_then(|x| x.into_dictionary());
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,6 +10,8 @@ pub mod core_device_proxy;
|
|||||||
pub mod crashreportcopymobile;
|
pub mod crashreportcopymobile;
|
||||||
#[cfg(feature = "debug_proxy")]
|
#[cfg(feature = "debug_proxy")]
|
||||||
pub mod debug_proxy;
|
pub mod debug_proxy;
|
||||||
|
#[cfg(feature = "diagnostics_relay")]
|
||||||
|
pub mod diagnostics_relay;
|
||||||
#[cfg(feature = "dvt")]
|
#[cfg(feature = "dvt")]
|
||||||
pub mod dvt;
|
pub mod dvt;
|
||||||
#[cfg(feature = "heartbeat")]
|
#[cfg(feature = "heartbeat")]
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ path = "src/lockdown.rs"
|
|||||||
name = "restore_service"
|
name = "restore_service"
|
||||||
path = "src/restore_service.rs"
|
path = "src/restore_service.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "ioreg"
|
||||||
|
path = "src/ioreg.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
idevice = { path = "../idevice", features = ["full"] }
|
idevice = { path = "../idevice", features = ["full"] }
|
||||||
tokio = { version = "1.43", features = ["io-util", "macros", "time", "full"] }
|
tokio = { version = "1.43", features = ["io-util", "macros", "time", "full"] }
|
||||||
|
|||||||
Reference in New Issue
Block a user