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