Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

idevice

A pure Rust library for interacting with iOS services. Inspired by libimobiledevicepymobiledevice3, and go-ios this library interfaces with lockdownd, usbmuxd, and RSD to perform actions on an iOS device that a Mac normally would.

For help and information, join the idevice Discord

Ask DeepWiki

State

IMPORTANT: Breaking changes will happen at each point release until 0.2.0. Pin your Cargo.toml to a specific version to avoid breakage.

This library is in development and research stage. Releases are being published to crates.io for use in other projects, but the API and feature-set are far from final or even planned.

Why use this?

libimobiledevice is a groundbreaking library. Unfortunately, it hasn't been seriously updated in a long time, and does not support many modern iOS features.

Libraries such as pymobiledevice3 and go-ios have popped up to fill that gap, but both lacked the support I needed for embedding into applications and server programs. Python requires an interpreter, and Go's current ability to be embedded in other languages is lacking.

This library is currently used in popular apps such as StikDebug, CrossCode and Protokolle. idevice has proven there is a need. It's currently deployed on tens of thousands of devices, all across the world.

Features

To keep dependency bloat and compile time down, everything is contained in features.

FeatureDescription
afcApple File Conduit for file system access.
amfiApple mobile file integrity service
bt_packet_loggerCapture Bluetooth packets.
companion_proxyManage paired Apple Watches.
core_device_proxyStart a secure tunnel to access protected services.
crashreportcopymobileCopy crash reports.
debug_proxySend GDB commands to the device.
diagnostics_relayAccess device diagnostics information (IORegistry, MobileGestalt, battery, NAND, device control).
dvtAccess Apple developer tools (e.g. Instruments).
heartbeatMaintain a heartbeat connection.
house_arrestManage files in app containers
installation_proxyManage app installation and uninstallation.
installcoordination_proxyManage app installation coordination.
location_simulationSimulate GPS locations on the device.
misagentManage provisioning profiles on the device.
mobile_image_mounterManage DDI images.
mobileactivationdActivate/Deactivate device.
mobilebackup2Manage backups.
pairPair the device.
pcapdCapture network packets.
preboard_serviceInterface with Preboard.
restore_serviceRestore service (recovery/reboot).
screenshotrTake screenshots.
springboardservicesControl SpringBoard (icons, wallpaper, orientation, etc.).
syslog_relayRelay system logs and OS trace logs from the device.
tcpConnect to devices over TCP.
tunnel_tcp_stackNaive in-process TCP stack for core_device_proxy.
tssMake requests to Apple's TSS servers. Partial support.
tunneldInterface with pymobiledevice3's tunneld.
usbmuxdConnect using the usbmuxd daemon.
xpcAccess protected services via XPC over RSD.
xctestLaunch XCTest runners and coordinate modern testmanagerd/XCTest sessions.
wdaMinimal WebDriverAgent bootstrap helpers and localhost bridge support.
notification_proxyPost and observe iOS notifications.

Planned/TODO

Finish the following:

  • webinspector

Implement the following:

  • file_relay

As this project is done in my free time within my busy schedule, there is no ETA for any of these. Feel free to contribute or donate!

Usage

idevice is purposefully verbose to allow for powerful configurations. No size fits all, but effort is made to reduce boilerplate via providers.

// enable the usbmuxd featureuse idevice::{lockdown::LockdowndClient,IdeviceService};use idevice::usbmuxd::{UsbmuxdAddr,UsbmuxdConnection},#[tokio::main]asyncfnmain(){// usbmuxd is Apple's daemon for connecting to devices over USB.// We'll ask usbmuxd for a deviceletmut usbmuxd = UsbmuxdConnection::default().await.expect("Unable to connect to usbmuxd");let devs = usbmuxd.get_devices().unwrap();if devs.is_empty(){eprintln!("No devices connected!");return;}// Create a provider to automatically create connections to the device.// Many services require opening multiple connections to get where you want.let provider = devs[0].to_provider(UsbmuxdAddr::from_env_var().unwrap(),0,"example-program")// ``connect`` takes an object with the provider traitletmut lockdown_client = matchLockdowndClient::connect(&provider).await{Ok(l) => l,Err(e) => {eprintln!("Unable to connect to lockdown: {e:?}");return;}};println!("{:?}", lockdown_client.get_value("ProductVersion").await);println!("{:?}",
lockdown_client
.start_session(&provider
.get_pairing_file().await.expect("failed to get pairing file")).await);println!("{:?}", lockdown_client.idevice.get_type().await.unwrap());println!("{:#?}", lockdown_client.get_all_values().await);}

More examples are in the tools crate and in the crate documentation.

XCTest / WDA

idevice also includes support for launching XCTest runners through the library's modern DVT/RSD path. This can be used to start WebDriverAgent-style runners on recent iOS versions.

The bundled CLI exposes this through the idevice-tools xctest command:

idevice-tools --udid <device-udid> xctest io.github.kor1k1.WebDriverAgentRunner.xctrunner

To wait for WDA and expose localhost bridge URLs for HTTP and MJPEG:

idevice-tools --udid <device-udid> xctest --bridge io.github.kor1k1.WebDriverAgentRunner.xctrunner

The current wda support is intentionally a bootstrap layer for readiness checks and session startup, rather than a complete long-lived WebDriver client.

FFI

For use in other languages, a small FFI crate has been created to start exposing idevice. Example C programs can be found in the ffi/examples directory.

C++

"Hey wait a second, there's a lot of C++ code in this library!!" C++ bindings have been made for many of idevice's features. This allows smooth and safer usage in C++ and Swift codebases.

Technical Explanation

There are so many layers and protocols in this library, many stacked on top of one another. It's difficult to describe the magnitude that is Apple's interfaces.

I would recommend reading the DeepWiki explanations and overviews to get an idea of how this library and their associated protocols work. But a general overview is:

Lockdown

  1. A lockdown service is accessible via a port given by lockdown
  2. Lockdown is accessible by USB or TCP via TLS
  3. USB is accessible via usbmuxd
  4. usbmuxd is accessed through a unix socket
  5. That Unix socket has its own protocol

RemoteXPC/RSD

  1. An RSD service is discovered through a RemoteXPC handshake response
  2. RemoteXPC is transferred over non-compliant HTTP/2
  3. That HTTP/2 is accessed through an NCM USB interface or CoreDeviceProxy
  4. CoreDeviceProxy is a lockdown service, see above

For more information about rppairing, I've written out the spec here

License

MIT

About

A crate to replace libimobiledevice in pure Rust

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages