/// <summary> /// Gets all TPLs that are required by the brlan (Frame Animation). /// </summary> /// <param name="wad"></param> /// <param name="banner"></param> /// <returns></returns> public static string[] GetBrlanTpls(WAD wad, bool banner) { if (!wad.HasBanner) return new string[0]; string bannerName = "banner"; if (!banner) bannerName = "icon"; for (int i = 0; i < wad.BannerApp.Nodes.Count; i++) { if (wad.BannerApp.StringTable[i].ToLower() == bannerName + ".bin") { U8 bannerFile = U8.Load(wad.BannerApp.Data[i]); string[] tpls = new string[0]; for (int y = 0; y < bannerFile.Nodes.Count; y++) { if (bannerFile.StringTable[y].ToLower() == bannerName + "_start.brlan" || bannerFile.StringTable[y].ToLower() == bannerName + "_loop.brlan" || bannerFile.StringTable[y].ToLower() == bannerName + ".brlan") { tpls = Shared.MergeStringArrays(tpls, getBrlanTpls(bannerFile.Data[y])); } } return tpls; } } return new string[0]; }
/// <summary> /// Loads an IOS wad to patch the es module. /// </summary> /// <param name="iosWad"></param> public void LoadIOS(ref WAD iosWad) { if ((iosWad.TitleID >> 32) != 1 || (iosWad.TitleID & 0xFFFFFFFF) < 3 || (iosWad.TitleID & 0xFFFFFFFF) > 255) throw new Exception("Only IOS WADs can be patched!"); wadFile = iosWad; getEsIndex(); }
private void doPack(object files, bool trucha) { string input = ((string[])files)[0]; string output = ((string[])files)[1]; try { WAD w = new WAD(); w.CreateNew(input); w.KeepOriginalFooter = true; w.FakeSign = trucha; w.Save(output); } catch (Exception ex) { return; } }
/// <summary> /// Loads a WAD file. /// </summary> /// <param name="wad"></param> /// <returns></returns> public static WAD Load(Stream wad) { WAD w = new WAD(); w.parseWad(wad); return w; }
/// <summary> /// Loads a WAD file. /// </summary> /// <param name="wadFile"></param> /// <returns></returns> public static WAD Load(byte[] wadFile) { WAD w = new WAD(); MemoryStream ms = new MemoryStream(wadFile); try { w.parseWad(ms); } catch { ms.Dispose(); throw; } ms.Dispose(); return w; }
/// <summary> /// Creates a WAD file from contents. /// </summary> /// <param name="cert"></param> /// <param name="tik"></param> /// <param name="tmd"></param> /// <param name="contents"></param> /// <returns></returns> public static WAD Create(CertificateChain cert, Ticket tik, TMD tmd, byte[][] contents) { WAD w = new WAD(); w.cert = cert; w.tik = tik; w.tmd = tmd; w.contents = new List<byte[]>(contents); w.wadHeader = new WAD_Header(); w.wadHeader.TmdSize = (uint)(484 + (tmd.Contents.Length * 36)); int contentSize = 0; for (int i = 0; i < contents.Length - 1; i++) contentSize += Shared.AddPadding(contents[i].Length); contentSize += contents[contents.Length - 1].Length; w.wadHeader.ContentSize = (uint)contentSize; for (int i = 0; i < w.tmd.Contents.Length; i++) if (w.tmd.Contents[i].Index == 0x0000) { try { w.bannerApp.LoadFile(contents[i]); w.hasBanner = true; } catch { w.hasBanner = false; } //Probably System Wad => No Banner App... break; } return w; }
private void clearAll() { tbAllLanguages.Text = string.Empty; tbDol.Text = string.Empty; tbDutch.Text = string.Empty; tbEnglish.Text = string.Empty; tbFrench.Text = string.Empty; tbGerman.Text = string.Empty; tbItalian.Text = string.Empty; tbKorean.Text = string.Empty; tbJapanese.Text = string.Empty; tbReplace.Text = string.Empty; tbSound.Text = string.Empty; tbSourceWad.Text = string.Empty; tbSpanish.Text = string.Empty; tbTitleID.Text = string.Empty; tbStartupIos.Text = string.Empty; lbCreatedValue.Text = string.Empty; lbxBannerTpls.Items.Clear(); lbxBrlanBanner.Items.Clear(); lbxBrlanIcon.Items.Clear(); lbxBrlytBanner.Items.Clear(); lbxBrlytIcon.Items.Clear(); lbxIconTpls.Items.Clear(); replacedBanner = string.Empty; replacedIcon = string.Empty; replacedSound = string.Empty; sourceWad = new WAD(); bannerBin = new U8(); newBannerBin = new U8(); iconBin = new U8(); newIconBin = new U8(); newSoundBin = new byte[0]; newDol = new byte[0]; sourceWad.Warning += new EventHandler<MessageEventArgs>(sourceWad_Warning); cbLz77.Checked = true; cbIconMakeTransparent.Checked = false; cbBannerMakeTransparent.Checked = false; bannerTransparents.Clear(); iconTransparents.Clear(); simpleForwarder.Clear(); complexForwarder.Clear(); }
private void doUnpack(object files) { string input = ((string[])files)[0]; string output = ((string[])files)[1]; try { WAD w = new WAD(); w.LoadFile(input); w.Unpack(output, false); } catch (Exception ex) { Environment.Exit(0); } }
private void doUnpack(object files) { setControls(false, false); string input = ((string[])files)[0]; string output = ((string[])files)[1]; try { WAD w = new WAD(); w.Progress +=new EventHandler<System.ComponentModel.ProgressChangedEventArgs>(unpack_Progress); w.LoadFile(input); w.Unpack(output, cidName); MessageBox.Show("Successfully unpacked WAD to:\n" + output, "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { setControls(true, false); } }
private void downloadTitle(string titleId, string titleVersion, string outputDir, string wadName, StoreType[] storeTypes) { fireDebug("Downloading Title {0} v{1}...", titleId, (string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion); if (storeTypes.Length < 1) { fireDebug(" No store types were defined..."); throw new Exception("You must at least define one store type!"); } string titleUrl = string.Format("{0}{1}/", nusUrl, titleId); bool storeEncrypted = false; bool storeDecrypted = false; bool storeWad = false; fireProgress(0); foreach (StoreType st in storeTypes) { switch (st) { case StoreType.DecryptedContent: fireDebug(" [=] Storing Decrypted Content..."); storeDecrypted = true; break; case StoreType.EncryptedContent: fireDebug(" [=] Storing Encrypted Content..."); storeEncrypted = true; break; case StoreType.WAD: fireDebug(" [=] Storing WAD..."); storeWad = true; break; case StoreType.All: fireDebug(" [=] Storing Decrypted Content..."); fireDebug(" [=] Storing Encrypted Content..."); fireDebug(" [=] Storing WAD..."); storeDecrypted = true; storeEncrypted = true; storeWad = true; break; case StoreType.Empty: break; } } /* * fireDebug(" - Checking for Internet connection..."); * if (!CheckInet()) * { fireDebug(" + Connection not found..."); throw new Exception("You're not connected to the internet!"); } */ if (!Directory.Exists(outputDir)) { Directory.CreateDirectory(outputDir); } if (!Directory.Exists(Path.Combine(outputDir, titleId))) { Directory.CreateDirectory(Path.Combine(outputDir, titleId)); } outputDir = Path.Combine(outputDir, titleId); string tmdFile = "tmd" + (string.IsNullOrEmpty(titleVersion) ? string.Empty : string.Format(".{0}", titleVersion)); //Download TMD fireDebug(" - Downloading TMD..."); TMD tmd; byte[] tmdFileWithCerts; try { tmdFileWithCerts = wcNus.DownloadData(titleUrl + tmdFile); tmd = TMD.Load(tmdFileWithCerts); } catch (Exception ex) { fireDebug(" + Downloading TMD Failed..."); throw new Exception("Downloading TMD Failed:\n" + ex.Message); } //Parse TMD fireDebug(" - Parsing TMD..."); if (string.IsNullOrEmpty(titleVersion)) { fireDebug(" + Title Version: {0}", tmd.TitleVersion); } fireDebug(" + {0} Contents", tmd.NumOfContents); if (!Directory.Exists(Path.Combine(outputDir, tmd.TitleVersion.ToString()))) { Directory.CreateDirectory(Path.Combine(outputDir, tmd.TitleVersion.ToString())); } outputDir = Path.Combine(outputDir, tmd.TitleVersion.ToString()); this.titleversion = tmd.TitleVersion; File.WriteAllBytes(Path.Combine(outputDir, tmdFile), tmd.ToByteArray()); fireProgress(5); //Download cetk fireDebug(" - Downloading Ticket..."); try { wcNus.DownloadFile(Path.Combine(titleUrl, "cetk"), Path.Combine(outputDir, "cetk")); } catch (Exception ex) { if (!continueWithoutTicket || !storeEncrypted) { fireDebug(" + Downloading Ticket Failed..."); throw new Exception("Downloading Ticket Failed:\n" + ex.Message); } if (!(File.Exists(Path.Combine(outputDir, "cetk")))) { storeDecrypted = false; storeWad = false; } } fireProgress(10); // Parse Ticket Ticket tik = new Ticket(); if (File.Exists(Path.Combine(outputDir, "cetk"))) { fireDebug(" + Parsing Ticket..."); tik = Ticket.Load(Path.Combine(outputDir, "cetk")); // DSi ticket? Must make sure to use DSi Key :D if (nusUrl == DSI_NUS_URL) { tik.DSiTicket = true; } } else { fireDebug(" + Ticket Unavailable..."); } string[] encryptedContents = new string[tmd.NumOfContents]; //Download Content for (int i = 0; i < tmd.NumOfContents; i++) { fireDebug(" - Downloading Content #{0} of {1}... ({2} bytes)", i + 1, tmd.NumOfContents, tmd.Contents[i].Size); fireProgress(((i + 1) * 60 / tmd.NumOfContents) + 10); if (useLocalFiles && File.Exists(Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8")))) { fireDebug(" + Using Local File, Skipping..."); continue; } try { wcNus.DownloadFile(titleUrl + tmd.Contents[i].ContentID.ToString("x8"), Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"))); encryptedContents[i] = tmd.Contents[i].ContentID.ToString("x8"); } catch (Exception ex) { fireDebug(" - Downloading Content #{0} of {1} failed...", i + 1, tmd.NumOfContents); throw new Exception("Downloading Content Failed:\n" + ex.Message); } } //Decrypt Content if (storeDecrypted || storeWad) { SHA1 s = SHA1.Create(); for (int i = 0; i < tmd.NumOfContents; i++) { fireDebug(" - Decrypting Content #{0} of {1}...", i + 1, tmd.NumOfContents); fireProgress(((i + 1) * 20 / tmd.NumOfContents) + 75); //Decrypt Content byte[] decryptedContent = decryptContent(File.ReadAllBytes(Path.Combine(outputDir, tmd.Contents[i].ContentID.ToString("x8"))), i, tik, tmd); Array.Resize(ref decryptedContent, (int)tmd.Contents[i].Size); //Check SHA1 byte[] newSha = s.ComputeHash(decryptedContent); if (!Shared.CompareByteArrays(newSha, tmd.Contents[i].Hash)) { fireDebug(@" + Hashes do not match! (Invalid Output)"); //throw new Exception(string.Format("Content #{0}: Hashes do not match!", i)); } //Write Decrypted Content File.WriteAllBytes(Path.Combine(outputDir, (tmd.Contents[i].ContentID.ToString("x8") + ".app")), decryptedContent); } s.Clear(); } //Pack Wad if (storeWad) { fireDebug(" - Building Certificate Chain..."); CertificateChain cert = CertificateChain.FromTikTmd(Path.Combine(outputDir, "cetk"), tmdFileWithCerts); byte[][] contents = new byte[tmd.NumOfContents][]; for (int i = 0; i < tmd.NumOfContents; i++) { contents[i] = File.ReadAllBytes(Path.Combine(outputDir, (tmd.Contents[i].ContentID.ToString("x8") + ".app"))); } fireDebug(" - Creating WAD..."); WAD wad = WAD.Create(cert, tik, tmd, contents); wad.RemoveFooter(); wadName = wadName.Replace("[v]", "v" + this.TitleVersion.ToString()); // fix by madri2 if (Path.DirectorySeparatorChar.ToString() != "/" && Path.AltDirectorySeparatorChar.ToString() != "/") { wadName = wadName.Replace("/", ""); } if (wadName.Contains(Path.DirectorySeparatorChar.ToString()) || wadName.Contains(Path.AltDirectorySeparatorChar.ToString())) { wad.Save(wadName); } else { wad.Save(Path.Combine(outputDir, wadName)); } } //Delete not wanted files if (!storeEncrypted) { fireDebug(" - Deleting Encrypted Contents..."); for (int i = 0; i < encryptedContents.Length; i++) { if (File.Exists(Path.Combine(outputDir, encryptedContents[i]))) { File.Delete(Path.Combine(outputDir, encryptedContents[i])); } } } if (storeWad && !storeDecrypted) { fireDebug(" - Deleting Decrypted Contents..."); for (int i = 0; i < encryptedContents.Length; i++) { if (File.Exists(Path.Combine(outputDir, (encryptedContents[i] + ".app")))) { File.Delete(Path.Combine(outputDir, (encryptedContents[i] + ".app"))); } } } if (!storeDecrypted && !storeEncrypted) { fireDebug(" - Deleting TMD and Ticket..."); File.Delete(Path.Combine(outputDir, tmdFile)); File.Delete(Path.Combine(outputDir, "cetk")); } fireDebug("Downloading Title {0} v{1} Finished...", titleId, tmd.TitleVersion /*(string.IsNullOrEmpty(titleVersion)) ? "[Latest]" : titleVersion*/); fireProgress(100); }