From 032587dd37c3f2917acf76411c3feb1658041f0d Mon Sep 17 00:00:00 2001 From: nab138 Date: Sat, 3 Jan 2026 00:56:51 -0500 Subject: [PATCH] Add increased memory limit --- Cargo.lock | 7 +-- isideload/Cargo.toml | 5 +- isideload/src/bundle.rs | 4 +- isideload/src/developer_session.rs | 77 +++++++++++++++++++++++++++++- isideload/src/lib.rs | 8 ++++ isideload/src/sideload.rs | 6 +++ 6 files changed, 99 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca0da05..02431bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -977,7 +977,7 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "isideload" -version = "0.1.24" +version = "0.1.25" dependencies = [ "hex", "idevice", @@ -985,6 +985,7 @@ dependencies = [ "obfstr", "openssl", "plist", + "reqwest", "serde", "sha1", "thiserror 2.0.17", @@ -1127,9 +1128,9 @@ dependencies = [ [[package]] name = "nab138_icloud_auth" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9974d0c323b02010a93eba36368153b8ca3003ac3f7fdd810b025d5ade24edca" +checksum = "69d9933f5f71168dd33e7e2b003cffd3a23116fd9a1df789525855bcf1d64173" dependencies = [ "aes", "aes-gcm", diff --git a/isideload/Cargo.toml b/isideload/Cargo.toml index 901d3da..bbd4d7e 100644 --- a/isideload/Cargo.toml +++ b/isideload/Cargo.toml @@ -3,7 +3,7 @@ name = "isideload" description = "Sideload iOS/iPadOS applications" license = "MPL-2.0" authors = ["Nicholas Sharp "] -version = "0.1.24" +version = "0.1.25" edition = "2024" repository = "https://github.com/nab138/isideload" documentation = "https://docs.rs/isideload" @@ -18,7 +18,7 @@ obfuscate = ["idevice/obfuscate", "icloud_auth/obfuscate", "dep:obfstr"] [dependencies] serde = { version = "1", features = ["derive"] } plist = { version = "1.7" } -icloud_auth = { version = "0.1.9", package = "nab138_icloud_auth" } +icloud_auth = { version = "0.1.10", package = "nab138_icloud_auth" } uuid = { version = "1.17.0", features = ["v4"] } zip = { version = "4.3", default-features = false, features = ["deflate"] } hex = "0.4" @@ -28,3 +28,4 @@ openssl = "0.10" zsign-rust = "0.1.7" thiserror = "2" obfstr = { version = "0.4", optional = true } +reqwest = { version = "0.11.14", features = ["blocking", "json", "default-tls"] } \ No newline at end of file diff --git a/isideload/src/bundle.rs b/isideload/src/bundle.rs index 579f27a..c8ba1b2 100644 --- a/isideload/src/bundle.rs +++ b/isideload/src/bundle.rs @@ -126,10 +126,10 @@ impl Bundle { let info_plist_path = self.bundle_dir.join("Info.plist"); let result = plist::to_file_binary(&info_plist_path, &self.app_info); - if result.is_err() { + if let Err(e) = result { return Err(Error::InvalidBundle(format!( "Failed to write Info.plist: {}", - result.unwrap_err() + e ))); } Ok(()) diff --git a/isideload/src/developer_session.rs b/isideload/src/developer_session.rs index a5c7ab7..2d2296e 100644 --- a/isideload/src/developer_session.rs +++ b/isideload/src/developer_session.rs @@ -4,10 +4,13 @@ use crate::{Error, obf}; use icloud_auth::AppleAccount; use idevice::pretty_print_dictionary; use plist::{Date, Dictionary, Value}; +use reqwest::header::{HeaderMap, HeaderName, HeaderValue}; use serde::{Deserialize, Serialize}; use std::sync::Arc; use uuid::Uuid; +use std::str::FromStr; + pub struct DeveloperSession { pub account: Arc, team: Option, @@ -53,7 +56,7 @@ impl DeveloperSession { .account .send_request(url, Some(request)) .await - .map_err(|e| Error::ICloudError(e))?; + .map_err(Error::ICloudError)?; let status_code = response .get("resultCode") @@ -645,6 +648,78 @@ impl DeveloperSession { encoded_profile, }) } + + // This is jank and I will do it better in the rewrite + pub async fn add_increased_memory_limit( + &self, + team: &DeveloperTeam, + app_id: &AppId, + ) -> Result<(), Error> { + let spd = self.account.spd.as_ref().unwrap(); + let app_token = self + .account + .get_app_token("com.apple.gs.xcode.auth") + .await?; + let valid_anisette = self.account.get_anisette().await; + + let mut headers = HeaderMap::new(); + headers.insert( + "Content-Type", + HeaderValue::from_static("application/vnd.api+json"), + ); + headers.insert( + "Accept", + HeaderValue::from_static("application/vnd.api+json"), + ); + headers.insert("Accept-Language", HeaderValue::from_static("en-us")); + headers.insert("User-Agent", HeaderValue::from_str("Xcode").unwrap()); + headers.insert( + HeaderName::from_str("X-Apple-I-Identity-Id").unwrap(), + HeaderValue::from_str(spd.get("adsid").unwrap().as_string().unwrap()).unwrap(), + ); + headers.insert( + HeaderName::from_str("X-Apple-GS-Token").unwrap(), + HeaderValue::from_str(&app_token.auth_token).unwrap(), + ); + + for (k, v) in valid_anisette.generate_headers(false, true, true) { + headers.insert( + HeaderName::from_bytes(k.as_bytes()).unwrap(), + HeaderValue::from_str(&v).unwrap(), + ); + } + + if let Ok(locale) = valid_anisette.get_header("x-apple-locale") { + headers.insert( + HeaderName::from_str("X-Apple-Locale").unwrap(), + HeaderValue::from_str(&locale).unwrap(), + ); + } + + let response = self + .account + .client + .patch(format!( + "https://developerservices2.apple.com/services/v1/bundleIds/{}", + app_id.app_id_id + )) + .headers(headers) + .body(format!( + "{{\"data\":{{\"relationships\":{{\"bundleIdCapabilities\":{{\"data\":[{{\"relationships\":{{\"capability\":{{\"data\":{{\"id\":\"INCREASED_MEMORY_LIMIT\",\"type\":\"capabilities\"}}}}}},\"type\":\"bundleIdCapabilities\",\"attributes\":{{\"settings\":[],\"enabled\":true}}}}]}}}},\"id\":\"{}\",\"attributes\":{{\"hasExclusiveManagedCapabilities\":false,\"teamId\":\"{}\",\"bundleType\":\"bundle\",\"identifier\":\"{}\",\"seedId\":\"{}\",\"name\":\"{}\"}},\"type\":\"bundleIds\"}}}}", + app_id.app_id_id, team.team_id, app_id.identifier, team.team_id, app_id.name + )) + .send() + .await + .map_err(|e| Error::ICloudError(icloud_auth::Error::ReqwestError(e)))?; + + let _response = response + .text() + .await + .map_err(|e| Error::ICloudError(icloud_auth::Error::ReqwestError(e)))?; + + //println!("Response: {:?}", response); + Ok(()) + } } #[derive(Debug, Clone)] diff --git a/isideload/src/lib.rs b/isideload/src/lib.rs index 5b59c71..c01f595 100644 --- a/isideload/src/lib.rs +++ b/isideload/src/lib.rs @@ -65,6 +65,8 @@ pub struct SideloadConfiguration<'a> { pub store_dir: std::path::PathBuf, /// Whether or not to revoke the certificate immediately after installation pub revoke_cert: bool, + /// Whether or not to add the increased memory limit entitlement to the app + pub add_increased_memory_limit: bool, } impl Default for SideloadConfiguration<'_> { @@ -80,6 +82,7 @@ impl<'a> SideloadConfiguration<'a> { logger: &DefaultLogger, store_dir: std::env::current_dir().unwrap(), revoke_cert: false, + add_increased_memory_limit: false, } } @@ -102,6 +105,11 @@ impl<'a> SideloadConfiguration<'a> { self.revoke_cert = revoke_cert; self } + + pub fn set_add_increased_memory_limit(mut self, add: bool) -> Self { + self.add_increased_memory_limit = add; + self + } } #[cfg(feature = "obfuscate")] diff --git a/isideload/src/sideload.rs b/isideload/src/sideload.rs index b9e742d..5b4e93c 100644 --- a/isideload/src/sideload.rs +++ b/isideload/src/sideload.rs @@ -257,6 +257,12 @@ pub async fn sideload_app( }; app_id.features = new_features; } + + if config.add_increased_memory_limit { + dev_session + .add_increased_memory_limit(&team, app_id) + .await?; + } } let group_identifier = format!(