Fix for livecontainer

This commit is contained in:
nab138
2025-11-26 21:14:49 -05:00
parent 3dd4395017
commit eab58f0e97
5 changed files with 52 additions and 30 deletions

6
Cargo.lock generated
View File

@@ -981,7 +981,7 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
[[package]] [[package]]
name = "isideload" name = "isideload"
version = "0.1.21" version = "0.1.22"
dependencies = [ dependencies = [
"hex", "hex",
"idevice", "idevice",
@@ -2839,9 +2839,9 @@ dependencies = [
[[package]] [[package]]
name = "zsign-rust" name = "zsign-rust"
version = "0.1.6" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e6f7303e79779f24807ebb43de1816334c6bbbfb1982785d21189bc1cb47f79" checksum = "f246eecd6b89f0ba582563ec68049f1b6f3498c455d78940355d0cfb09b38379"
dependencies = [ dependencies = [
"bindgen", "bindgen",
"cc", "cc",

View File

@@ -3,7 +3,7 @@ name = "isideload"
description = "Sideload iOS/iPadOS applications" description = "Sideload iOS/iPadOS applications"
license = "MPL-2.0" license = "MPL-2.0"
authors = ["Nicholas Sharp <nab@nabdev.me>"] authors = ["Nicholas Sharp <nab@nabdev.me>"]
version = "0.1.21" version = "0.1.22"
edition = "2024" edition = "2024"
repository = "https://github.com/nab138/isideload" repository = "https://github.com/nab138/isideload"
documentation = "https://docs.rs/isideload" documentation = "https://docs.rs/isideload"
@@ -24,5 +24,5 @@ hex = "0.4"
sha1 = "0.10" sha1 = "0.10"
idevice = { version = "0.1.46", features = ["afc", "installation_proxy", "ring"], default-features = false } idevice = { version = "0.1.46", features = ["afc", "installation_proxy", "ring"], default-features = false }
openssl = "0.10" openssl = "0.10"
zsign-rust = "0.1.6" zsign-rust = "0.1.7"
thiserror = "2" thiserror = "2"

View File

@@ -7,12 +7,13 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
#[derive(Debug)]
pub struct Bundle { pub struct Bundle {
pub app_info: Dictionary, pub app_info: Dictionary,
pub bundle_dir: PathBuf, pub bundle_dir: PathBuf,
app_extensions: Vec<Bundle>, app_extensions: Vec<Bundle>,
_frameworks: Vec<Bundle>, frameworks: Vec<Bundle>,
_libraries: Vec<String>, _libraries: Vec<String>,
} }
@@ -81,7 +82,7 @@ impl Bundle {
app_info, app_info,
bundle_dir: bundle_path, bundle_dir: bundle_path,
app_extensions, app_extensions,
_frameworks: frameworks, frameworks,
_libraries: libraries, _libraries: libraries,
}) })
} }
@@ -113,6 +114,14 @@ impl Bundle {
&mut self.app_extensions &mut self.app_extensions
} }
pub fn frameworks(&self) -> &[Bundle] {
&self.frameworks
}
pub fn frameworks_mut(&mut self) -> &mut [Bundle] {
&mut self.frameworks
}
pub fn write_info(&self) -> Result<(), Error> { pub fn write_info(&self) -> Result<(), Error> {
let info_plist_path = self.bundle_dir.join("Info.plist"); let info_plist_path = self.bundle_dir.join("Info.plist");
let result = plist::to_file_binary(&info_plist_path, &self.app_info); let result = plist::to_file_binary(&info_plist_path, &self.app_info);

View File

@@ -63,8 +63,6 @@ pub struct SideloadConfiguration<'a> {
pub store_dir: std::path::PathBuf, pub store_dir: std::path::PathBuf,
/// Whether or not to revoke the certificate immediately after installation /// Whether or not to revoke the certificate immediately after installation
pub revoke_cert: bool, pub revoke_cert: bool,
/// Whether or not to force SideStore App Group (fixes LiveContainer+SideStore issues)
pub force_sidestore_app_group: bool,
} }
impl Default for SideloadConfiguration<'_> { impl Default for SideloadConfiguration<'_> {
@@ -80,7 +78,6 @@ impl<'a> SideloadConfiguration<'a> {
logger: &DefaultLogger, logger: &DefaultLogger,
store_dir: std::env::current_dir().unwrap(), store_dir: std::env::current_dir().unwrap(),
revoke_cert: false, revoke_cert: false,
force_sidestore_app_group: false,
} }
} }
@@ -103,9 +100,4 @@ impl<'a> SideloadConfiguration<'a> {
self.revoke_cert = revoke_cert; self.revoke_cert = revoke_cert;
self self
} }
pub fn set_force_sidestore_app_group(mut self, force: bool) -> Self {
self.force_sidestore_app_group = force;
self
}
} }

View File

@@ -105,7 +105,14 @@ pub async fn sideload_app(
}; };
let mut app = Application::new(app_path)?; let mut app = Application::new(app_path)?;
let is_sidestore = app.bundle.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore"; let is_sidestore = app.bundle.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore";
let is_lc_and_sidestore = app
.bundle
.frameworks()
.iter()
.any(|f| f.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore");
let main_app_bundle_id = match app.bundle.bundle_identifier() { let main_app_bundle_id = match app.bundle.bundle_identifier() {
Some(id) => id.to_string(), Some(id) => id.to_string(),
None => { None => {
@@ -254,35 +261,44 @@ pub async fn sideload_app(
let group_identifier = format!( let group_identifier = format!(
"group.{}", "group.{}",
if config.force_sidestore_app_group { if is_lc_and_sidestore {
format!("com.SideStore.SideStore.{}", team.team_id) format!("com.SideStore.SideStore.{}", team.team_id)
} else { } else {
main_app_id_str.clone() main_app_id_str.clone()
} }
); );
if is_sidestore { if is_sidestore || is_lc_and_sidestore {
app.bundle.app_info.insert( app.bundle.app_info.insert(
"ALTAppGroups".to_string(), "ALTAppGroups".to_string(),
plist::Value::Array(vec![plist::Value::String(group_identifier.clone())]), plist::Value::Array(vec![plist::Value::String(group_identifier.clone())]),
); );
app.bundle.app_info.insert( let target_bundle = if is_lc_and_sidestore {
"ALTCertificateID".to_string(), app.bundle
plist::Value::String(cert.get_serial_number().unwrap()), .frameworks_mut()
); .iter_mut()
.find(|fw| fw.bundle_identifier().unwrap_or("") == "com.SideStore.SideStore")
} else {
Some(&mut app.bundle)
};
match cert.to_pkcs12(&cert.machine_id) { if let Some(target_bundle) = target_bundle {
Ok(p12_bytes) => { target_bundle.app_info.insert(
let alt_cert_path = app.bundle.bundle_dir.join("ALTCertificate.p12"); "ALTCertificateID".to_string(),
if alt_cert_path.exists() { plist::Value::String(cert.get_serial_number().unwrap()),
std::fs::remove_file(&alt_cert_path).map_err(Error::Filesystem)?; );
match cert.to_pkcs12(&cert.machine_id) {
Ok(p12_bytes) => {
let alt_cert_path = target_bundle.bundle_dir.join("ALTCertificate.p12");
let mut file =
std::fs::File::create(&alt_cert_path).map_err(Error::Filesystem)?;
file.write_all(&p12_bytes).map_err(Error::Filesystem)?;
} }
Err(e) => return error_and_return(logger, e),
let mut file = std::fs::File::create(&alt_cert_path).map_err(Error::Filesystem)?;
file.write_all(&p12_bytes).map_err(Error::Filesystem)?;
} }
Err(e) => return error_and_return(logger, e),
} }
} }
@@ -384,11 +400,16 @@ pub async fn sideload_app(
for ext in app.bundle.app_extensions_mut() { for ext in app.bundle.app_extensions_mut() {
ext.write_info()?; ext.write_info()?;
} }
for ext in app.bundle.frameworks_mut() {
ext.write_info()?;
}
match ZSignOptions::new(app.bundle.bundle_dir.to_str().unwrap()) match ZSignOptions::new(app.bundle.bundle_dir.to_str().unwrap())
.with_cert_file(cert.get_certificate_file_path().to_str().unwrap()) .with_cert_file(cert.get_certificate_file_path().to_str().unwrap())
.with_pkey_file(cert.get_private_key_file_path().to_str().unwrap()) .with_pkey_file(cert.get_private_key_file_path().to_str().unwrap())
.with_prov_file(profile_path.to_str().unwrap()) .with_prov_file(profile_path.to_str().unwrap())
.with_force()
.with_disable_cache()
.sign() .sign()
{ {
Ok(_) => {} Ok(_) => {}