public static void Main(string[] args) { // CreateDirectory(...) sometimes fails unless we wait (race condition?) if (Directory.Exists(keyDir)) { Directory.Delete(keyDir, true); } Thread.Sleep(100); Directory.CreateDirectory(keyDir); #if !DEBUG makeBinaryPlists = true; #endif if (makeBinaryPlists) { if (!File.Exists(plutil)) { makeBinaryPlists = false; Console.WriteLine("WARNING: plutil not found! Binary plists will NOT be generated."); } } // TODO: Parse the key page using XPath (action=render) [id tags] EnumerateFirmwareListAndSaveKeys("Firmware/Apple_TV"); //EnumerateFirmwareListAndSaveKeys("Firmware/Apple_Watch"); EnumerateFirmwareListAndSaveKeys("Firmware/iPad"); EnumerateFirmwareListAndSaveKeys("Firmware/iPad_mini"); EnumerateFirmwareListAndSaveKeys("Firmware/iPhone"); EnumerateFirmwareListAndSaveKeys("Firmware/iPod_touch"); // Build version listing PlistDict plistRoot = new PlistDict(); foreach (var deviceList in versionsList) { List <FirmwareVersion> versions = deviceList.Value; PlistArray deviceArr = new PlistArray(new IPlistElement[versions.Count]); for (int i = 0; i < versions.Count; i++) { FirmwareVersion ver = versions[i]; PlistDict versionDict = new PlistDict(); versionDict.Add("Build", new PlistString(ver.Build)); versionDict.Add("Version", new PlistString(ver.Version)); versionDict.Add("Has Keys", new PlistBool(ver.HasKeys)); deviceArr.Set(i, versionDict); } plistRoot.Add(deviceList.Key, deviceArr); } // Save version listing PlistDocument versionDoc = new PlistDocument(plistRoot); string keyListPath = Path.Combine(keyDir, "KeyList.plist"); versionDoc.Save(keyListPath, PlistDocumentType.Xml); ConvertPlist(keyListPath); }
private static void InitDevice(ref List <ComboBoxEntry> device, PlistArray versionArr) { device = new List <ComboBoxEntry>(); foreach (IPlistElement elem in versionArr.Value) { PlistDict dict = (PlistDict)elem; string build = dict.Get <PlistString>("Build").Value; string version = dict.Get <PlistString>("Version").Value; //bool hasKeys = dict.Get<PlistBool>("Has Keys").Value; device.Add(new ComboBoxEntry( build, $"{version} ({build})")); } }
private void ProcessFirmwareItem(PlistDict rootNode, string key) { KeyGridItem controls = keyGrid[key]; if (rootNode.Exists(key)) { PlistDict node = rootNode.Get <PlistDict>(key); if (node.Get <PlistBool>("Encryption").Value) { controls.EncryptedGrid.Visibility = Visibility.Visible; controls.EncryptedIV.Text = node.Get <PlistString>("IV").Value; controls.EncryptedKey.Text = node.Get <PlistString>("Key").Value; controls.EncryptedFileName.Text = node.Get <PlistString>("File Name").Value; controls.NotEncryptedGrid.Visibility = Visibility.Collapsed; controls.NotEncryptedFileName.Text = ""; } else { controls.EncryptedGrid.Visibility = Visibility.Collapsed; controls.EncryptedIV.Text = ""; controls.EncryptedKey.Text = ""; controls.EncryptedFileName.Text = ""; controls.NotEncryptedGrid.Visibility = Visibility.Visible; controls.NotEncryptedFileName.Text = node.Get <PlistString>("File Name").Value; } } else { controls.EncryptedGrid.Visibility = Visibility.Collapsed; controls.EncryptedIV.Text = ""; controls.EncryptedKey.Text = ""; controls.EncryptedFileName.Text = ""; controls.NotEncryptedGrid.Visibility = Visibility.Collapsed; controls.NotEncryptedFileName.Text = ""; } }
private static PlistDict BuildPlist(Dictionary <string, string> data) { PlistDict dict = new PlistDict(); int length; string debug = data["Codename"] + " " + data["Build"] + " (" + data["Device"] + "): "; PlistDict elem; // We could save some space by saving the IVs and keys in Base64 (len*4/3) // instead of a hex string (len*2) (use PlistData) foreach (string key in data.Keys) { switch (key) { case "Version": string temp = data["Version"]; if (temp.Contains("b") || temp.Contains("[")) { // will need to be updated for beta support Match match = new Regex(@"^([\d\.]+)[^(]+\(([\d\.]+)").Match(temp); temp = $"{match.Groups[1].Value} ({match.Groups[2].Value})"; Console.WriteLine(" <<>> \"{0}\" --> \"{1}\"", data[key], temp); } dict.Add("Version", new PlistString(temp)); break; case "Build": case "Device": case "Codename": case "Download URL": case "Baseband": dict.Add(key, new PlistString(data[key])); break; case "RootFS": elem = new PlistDict(); elem.Add("File Name", new PlistString(data["RootFS"] + ".dmg")); elem.Add("Key", new PlistString(data["RootFSKey"])); length = data["RootFSKey"].Length; Debug.Assert(length == 72 || length == 4, $"{debug}data[\"RootFSKey\"].Length ({length}) != 72)"); dict.Add("Root FS", elem); break; /*case "GMRootFS": * elem = new PlistDict(); * elem.Add("File Name", new PlistString(data["GMRootFS"] + ".dmg")); * elem.Add("Key", new PlistString(data["GMRootFSKey"])); * length = data["GMRootFSKey"].Length; * Debug.Assert(length == 72 || length == 4, $"{debug}data[\"GMRootFSKey\"].Length ({length}) != 72"); * dict.Add("GM Root FS", elem); * break;*/ case "UpdateRamdisk": case "RestoreRamdisk": elem = new PlistDict(); elem.Add("File Name", new PlistString(data[key] + ".dmg")); if (data[key + "IV"] == "Not Encrypted") { elem.Add("Encryption", new PlistBool(false)); } else { elem.Add("Encryption", new PlistBool(true)); elem.Add("IV", new PlistString(data[key + "IV"])); elem.Add("Key", new PlistString(data[key + "Key"])); length = data[key + "IV"].Length; Debug.Assert(length == 32 || length == 4, $"{debug}data[\"{key}IV\"].Length ({length}) != 32"); length = data[key + "Key"].Length; Debug.Assert(length == 32 || length == 64 || length == 4, $"{debug}data[\"{key}Key\"].Length ({length}) != (32 || 64)"); } dict.Add(key.Replace("Ramdisk", " Ramdisk"), elem); break; case "AppleLogo": case "BatteryCharging": case "BatteryCharging0": case "BatteryCharging1": case "BatteryFull": case "BatteryLow0": case "BatteryLow1": case "DeviceTree": case "GlyphCharging": case "GlyphPlugin": case "iBEC": case "iBoot": case "iBSS": case "Kernelcache": case "LLB": case "NeedService": case "RecoveryMode": case "SEP-Firmware": elem = new PlistDict(); elem.Add("File Name", new PlistString(data[key])); if (data[key + "IV"] == "Not Encrypted") { elem.Add("Encryption", new PlistBool(false)); } else { elem.Add("Encryption", new PlistBool(true)); elem.Add("IV", new PlistString(data[key + "IV"])); elem.Add("Key", new PlistString(data[key + "Key"])); length = data[key + "IV"].Length; Debug.Assert(length == 32 || length == 4, $"{debug}data[\"{key}IV\"].Length ({length}) != 32"); length = data[key + "Key"].Length; Debug.Assert(length == 32 || length == 64 || length == 4, $"{debug}data[\"{key}Key\"].Length ({length}) != (32 || 64)"); } dict.Add(key, elem); break; default: // Ignore GM keys for now if (key.StartsWith("GM")) { break; } Debug.Assert(key.EndsWith("IV") || key.EndsWith("Key") || key.EndsWith("KBAG"), $"Unknown key: {key}"); break; } } return(dict); }
private static void InitDevices() { Stream keyListPlist = Globals.GetStream("KeyList.plist"); PlistDocument keyList = new PlistDocument(keyListPlist); PlistDict rootNode = (PlistDict)keyList.RootNode; keyListPlist.Close(); // Apple TV InitDevice(ref AppleTV21, rootNode.Get <PlistArray>("AppleTV2,1")); InitDevice(ref AppleTV31, rootNode.Get <PlistArray>("AppleTV3,1")); InitDevice(ref AppleTV32, rootNode.Get <PlistArray>("AppleTV3,2")); InitDevice(ref AppleTV53, rootNode.Get <PlistArray>("AppleTV5,3")); // iPad InitDevice(ref iPad11, rootNode.Get <PlistArray>("iPad1,1")); InitDevice(ref iPad21, rootNode.Get <PlistArray>("iPad2,1")); InitDevice(ref iPad22, rootNode.Get <PlistArray>("iPad2,2")); InitDevice(ref iPad23, rootNode.Get <PlistArray>("iPad2,3")); InitDevice(ref iPad24, rootNode.Get <PlistArray>("iPad2,4")); InitDevice(ref iPad31, rootNode.Get <PlistArray>("iPad3,1")); InitDevice(ref iPad32, rootNode.Get <PlistArray>("iPad3,2")); InitDevice(ref iPad33, rootNode.Get <PlistArray>("iPad3,3")); InitDevice(ref iPad34, rootNode.Get <PlistArray>("iPad3,4")); InitDevice(ref iPad35, rootNode.Get <PlistArray>("iPad3,5")); InitDevice(ref iPad36, rootNode.Get <PlistArray>("iPad3,6")); InitDevice(ref iPad41, rootNode.Get <PlistArray>("iPad4,1")); InitDevice(ref iPad42, rootNode.Get <PlistArray>("iPad4,2")); InitDevice(ref iPad43, rootNode.Get <PlistArray>("iPad4,3")); InitDevice(ref iPad53, rootNode.Get <PlistArray>("iPad5,3")); InitDevice(ref iPad54, rootNode.Get <PlistArray>("iPad5,4")); InitDevice(ref iPad63, rootNode.Get <PlistArray>("iPad6,3")); InitDevice(ref iPad64, rootNode.Get <PlistArray>("iPad6,4")); InitDevice(ref iPad67, rootNode.Get <PlistArray>("iPad6,7")); InitDevice(ref iPad68, rootNode.Get <PlistArray>("iPad6,8")); // iPad mini InitDevice(ref iPad25, rootNode.Get <PlistArray>("iPad2,5")); InitDevice(ref iPad26, rootNode.Get <PlistArray>("iPad2,6")); InitDevice(ref iPad27, rootNode.Get <PlistArray>("iPad2,7")); InitDevice(ref iPad44, rootNode.Get <PlistArray>("iPad4,4")); InitDevice(ref iPad45, rootNode.Get <PlistArray>("iPad4,5")); InitDevice(ref iPad46, rootNode.Get <PlistArray>("iPad4,6")); InitDevice(ref iPad47, rootNode.Get <PlistArray>("iPad4,7")); InitDevice(ref iPad48, rootNode.Get <PlistArray>("iPad4,8")); InitDevice(ref iPad49, rootNode.Get <PlistArray>("iPad4,9")); InitDevice(ref iPad51, rootNode.Get <PlistArray>("iPad5,1")); InitDevice(ref iPad52, rootNode.Get <PlistArray>("iPad5,2")); // iPhone InitDevice(ref iPhone11, rootNode.Get <PlistArray>("iPhone1,1")); InitDevice(ref iPhone12, rootNode.Get <PlistArray>("iPhone1,2")); InitDevice(ref iPhone21, rootNode.Get <PlistArray>("iPhone2,1")); InitDevice(ref iPhone31, rootNode.Get <PlistArray>("iPhone3,1")); InitDevice(ref iPhone32, rootNode.Get <PlistArray>("iPhone3,2")); InitDevice(ref iPhone33, rootNode.Get <PlistArray>("iPhone3,3")); InitDevice(ref iPhone41, rootNode.Get <PlistArray>("iPhone4,1")); InitDevice(ref iPhone51, rootNode.Get <PlistArray>("iPhone5,1")); InitDevice(ref iPhone52, rootNode.Get <PlistArray>("iPhone5,2")); InitDevice(ref iPhone53, rootNode.Get <PlistArray>("iPhone5,3")); InitDevice(ref iPhone54, rootNode.Get <PlistArray>("iPhone5,4")); InitDevice(ref iPhone61, rootNode.Get <PlistArray>("iPhone6,1")); InitDevice(ref iPhone62, rootNode.Get <PlistArray>("iPhone6,2")); InitDevice(ref iPhone71, rootNode.Get <PlistArray>("iPhone7,1")); InitDevice(ref iPhone72, rootNode.Get <PlistArray>("iPhone7,2")); InitDevice(ref iPhone81, rootNode.Get <PlistArray>("iPhone8,1")); InitDevice(ref iPhone82, rootNode.Get <PlistArray>("iPhone8,2")); InitDevice(ref iPhone84, rootNode.Get <PlistArray>("iPhone8,4")); // iPod touch InitDevice(ref iPod11, rootNode.Get <PlistArray>("iPod1,1")); InitDevice(ref iPod21, rootNode.Get <PlistArray>("iPod2,1")); InitDevice(ref iPod31, rootNode.Get <PlistArray>("iPod3,1")); InitDevice(ref iPod41, rootNode.Get <PlistArray>("iPod4,1")); InitDevice(ref iPod51, rootNode.Get <PlistArray>("iPod5,1")); InitDevice(ref iPod71, rootNode.Get <PlistArray>("iPod7,1")); }