diff --git a/README.md b/README.md index 2a8f5cc..3e8c107 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,4 @@ Before opening SparseBox, you have to close SideStore from app switcher. This is - @JJTech0130: SparseRestore and backup exploit - @PoomSmart: MobileGestalt dump - @libimobiledevice +- [the sneakyf1shy apple intelligence tutorial](https://gist.github.com/f1shy-dev/23b4a78dc283edd30ae2b2e6429129b5#file-best_sae_trick-md) diff --git a/Resources/eligibility.plist b/Resources/eligibility.plist new file mode 100644 index 0000000..3bbcb45 --- /dev/null +++ b/Resources/eligibility.plist @@ -0,0 +1,47 @@ + + + + + OS_ELIGIBILITY_DOMAIN_CALCIUM + + os_eligibility_answer_source_t + 1 + os_eligibility_answer_t + 2 + status + + OS_ELIGIBILITY_INPUT_CHINA_CELLULAR + 2 + + + OS_ELIGIBILITY_DOMAIN_GREYMATTER + + context + + OS_ELIGIBILITY_CONTEXT_ELIGIBLE_DEVICE_LANGUAGES + + en + + + os_eligibility_answer_source_t + 1 + os_eligibility_answer_t + 4 + status + + OS_ELIGIBILITY_INPUT_DEVICE_LANGUAGE + 3 + OS_ELIGIBILITY_INPUT_DEVICE_REGION_CODE + 3 + OS_ELIGIBILITY_INPUT_EXTERNAL_BOOT_DRIVE + 3 + OS_ELIGIBILITY_INPUT_GENERATIVE_MODEL_SYSTEM + 3 + OS_ELIGIBILITY_INPUT_SHARED_IPAD + 3 + OS_ELIGIBILITY_INPUT_SIRI_LANGUAGE + 3 + + + + \ No newline at end of file diff --git a/Sources/ContentView.swift b/Sources/ContentView.swift index dda6019..b8002f0 100644 --- a/Sources/ContentView.swift +++ b/Sources/ContentView.swift @@ -11,8 +11,10 @@ struct ContentView: View { let os = ProcessInfo().operatingSystemVersion let origMGURL, modMGURL, featFlagsURL: URL @AppStorage("PairingFile") var pairingFile: String? + @State var eligibilityData = Data() @State var featureFlagsData = Data() @State var mobileGestalt: NSMutableDictionary + @State var productType = machineName() @State var minimuxerReady = false @State var reboot = true @State var showPairingFileImporter = false @@ -64,7 +66,7 @@ struct ContentView: View { Toggle("Charge limit", isOn: bindingForMGKeys(["37NVydb//GP/GrhuTN+exg"])) .disabled(requiresVersion(17)) Toggle("Crash Detection (might not work)", isOn: bindingForMGKeys(["HCzWusHQwZDea6nNhaKndw"])) - Toggle("Dynamic Island (17.4+ method)", isOn: bindingForMGKeys(["YlEtTtHlNesRBMal1CqRaA"])) + Toggle("Dynamic Island (17.4+, might not work)", isOn: bindingForMGKeys(["YlEtTtHlNesRBMal1CqRaA"])) .disabled(requiresVersion(17, 4)) Toggle("Internal Storage info", isOn: bindingForMGKeys(["LBJfwOEzExRxzlAnSuI7eg"])) Toggle("Metal HUD for all apps", isOn: bindingForMGKeys(["EqrsVvjcYDdxHBiQmGhAWw"])) @@ -73,10 +75,29 @@ struct ContentView: View { if let isSE = UIDevice.perform(Selector("_hasHomeButton")) { Toggle("Tap to Wake (iPhone SE)", isOn: bindingForMGKeys(["yZf3GTRMGTuwSV/lD7Cagw"])) } + } header: { + Text("MobileGestalt") + } + Section { + Picker("Device model", selection:$productType) { + Text("unchanged").tag(ContentView.machineName()) + if UIDevice.current.userInterfaceIdiom == .pad { + Text("iPad Pro 11 inch 5th Gen").tag("iPad16,3") + } else { + Text("iPhone 15 Pro Max").tag("iPhone16,2") + Text("iPhone 16 Pro Max").tag("iPhone17,2") + } + } + //.disabled(requiresVersion(18, 1)) + } header: { + Text("Device spoofing") + } footer: { + Text("Only change device model if you're downloading Apple Intelligence models. Face ID may break.") } Section { Toggle("Reboot after finish restoring", isOn: $reboot) Button("Apply changes") { + saveProductType() try! mobileGestalt.write(to: modMGURL) applyChanges() } @@ -128,6 +149,9 @@ Thanks to: pairingFile = altPairingFile } startMinimuxer() + + let cacheExtra = mobileGestalt["CacheExtra"] as! NSMutableDictionary + productType = cacheExtra["h9jDsbgj7xIVeIQ8S3/X3Q"] as! String } } @@ -159,21 +183,24 @@ Thanks to: } func bindingForAppleIntelligence() -> Binding { + let cacheExtra = mobileGestalt["CacheExtra"] as! NSMutableDictionary let key = "A62OafQ85EJAiiqKn4agtg" return Binding( get: { - if let value = (mobileGestalt["CacheExtra"] as! NSMutableDictionary)[key] as? Int? { + if let value = cacheExtra[key] as? Int? { return value == 1 } return false }, set: { enabled in - let cacheExtra = mobileGestalt["CacheExtra"] as! NSMutableDictionary if enabled { + eligibilityData = try! Data(contentsOf: Bundle.main.url(forResource: "eligibility", withExtension: "plist")!) + cacheExtra[key] = 1 featureFlagsData = try! Data(contentsOf: Bundle.main.url(forResource: "FeatureFlags_Global", withExtension: "plist")!) cacheExtra[key] = 1 } else { featureFlagsData = try! PropertyListSerialization.data(fromPropertyList: [:], format: .xml, options: 0) + eligibilityData = featureFlagsData // just remove the key as it will be pulled from device tree if missing cacheExtra.removeObject(forKey: key) } @@ -182,15 +209,15 @@ Thanks to: } func bindingForMGKeys(_ keys: [String], type: T.Type = Int.self, defaultValue: T? = 0, enableValue: T? = 1) -> Binding { - Binding( + let cacheExtra = mobileGestalt["CacheExtra"] as! NSMutableDictionary + return Binding( get: { - if let value = (mobileGestalt["CacheExtra"] as! NSMutableDictionary)[keys.first!] as? T?, let enableValue { + if let value = cacheExtra[keys.first!] as? T?, let enableValue { return value == enableValue } return false }, set: { enabled in - let cacheExtra = mobileGestalt["CacheExtra"] as! NSMutableDictionary for key in keys { if enabled { cacheExtra[key] = enableValue @@ -206,10 +233,28 @@ Thanks to: func generateFilesToRestore() -> [FileToRestore] { return [ FileToRestore(from: modMGURL, to: URL(filePath: "/var/containers/Shared/SystemGroup/systemgroup.com.apple.mobilegestaltcache/Library/Caches/com.apple.MobileGestalt.plist"), owner: 501, group: 501), - FileToRestore(contents: featureFlagsData, to: URL(filePath: "/var/preferences/FeatureFlags/Global.plist")) + FileToRestore(contents: eligibilityData, to: URL(filePath: "/var/db/eligibilityd/eligibility.plist")), + FileToRestore(contents: featureFlagsData, to: URL(filePath: "/var/preferences/FeatureFlags/Global.plist")), ] } + // https://stackoverflow.com/questions/26028918/how-to-determine-the-current-iphone-device-model + // read device model from kernel + static func machineName() -> String { + var systemInfo = utsname() + uname(&systemInfo) + let machineMirror = Mirror(reflecting: systemInfo.machine) + return machineMirror.children.reduce("") { identifier, element in + guard let value = element.value as? Int8, value != 0 else { return identifier } + return identifier + String(UnicodeScalar(UInt8(value))) + } + } + + func saveProductType() { + let cacheExtra = mobileGestalt["CacheExtra"] as! NSMutableDictionary + cacheExtra["h9jDsbgj7xIVeIQ8S3/X3Q"] = productType + } + func startMinimuxer() { guard pairingFile != nil else { return