private string[] getContentDownloadUrls(TMD_Content content) { string contentId = content.ContentID.ToString("x8"); string url = getContentUrl(contentId); if (((ushort)content.Type & 0x02) == 0x02) // Need download h3 { string h3url = getContentUrl(contentId + ".h3"); string h3Path = Path.Combine(mOutputDir, contentId + ".h3"); return(new string[] { url, h3url }); } return(new string[] { url }); }
public void exportTitle() { // Create dirs if (!Directory.Exists(mOutputDirBase)) { Directory.CreateDirectory(mOutputDirBase); } //Download TMD fireDebug(" - TMD... "); TMD tmd = downloadTmdToMemory(); //fireDebug(" {0} Contents.\r\n", tmd.NumOfContents); mBytesTotal = 0; for (int i = 0; i < tmd.NumOfContents; i++) { mBytesTotal += (long)tmd.Contents[i].Size; } fireDebug(" Contents:" + tmd.NumOfContents + ", Size:" + ConvertUnit(mBytesTotal) + "\r\n"); string[] encryptedContents = new string[tmd.NumOfContents]; mBytesTotalDone = 0; var listFilePath = Path.Combine(mOutputDirBase, mTitleId + "_LIST_" + ConvertUnit(mBytesTotal, "") + ".txt"); StringWriter sw = new StringWriter(); sw.WriteLine(getTmdUrl()); //Export Content for (int i = 0; i < tmd.NumOfContents; i++) { TMD_Content content = tmd.Contents[i]; var list = getContentDownloadUrls(content); foreach (var j in list) { sw.WriteLine(j); } } File.WriteAllText(listFilePath, sw.ToString()); }
private void downloadContent(TMD_Content content) { string contentId = content.ContentID.ToString("x8"); //fireDebug("Downloading Content ID: {0} ...", contentId); if (!CheckInet()) { fireDebug(" Connection not found..."); throw new Exception("You're not connected to the internet!"); } string url = getContentUrl(contentId); string filePath = Path.Combine(mOutputDir, contentId + ".app"); FileInfo fi = new FileInfo(filePath); if (mUseLocalFiles && fi.Exists && fi.Length == (long)content.Size) { fireDebug("ig app! ", contentId); } else { downloadFileAndWait(url, filePath); } if (((ushort)content.Type & 0x02) == 0x02) // Need download h3 { string h3url = string.Format("{0}{1}/{2}", mNusUrl, mTitleId, contentId + ".h3"); string h3Path = Path.Combine(mOutputDir, contentId + ".h3"); FileInfo h3fi = new FileInfo(h3Path); if (mUseLocalFiles && h3fi.Exists && (h3fi.Length == 20 || h3fi.Length == 40)) { fireDebug("ig h3! ", contentId); } else { mWcNus.DownloadFile(h3url, h3Path); } } //fireDebug("Downloading Content {0} Finished...", contentId); }
private void parseTmd(Stream tmdFile) { fireDebug("Pasing TMD..."); tmdFile.Seek(0, SeekOrigin.Begin); byte[] temp = new byte[8]; fireDebug(" Reading Signature Exponent... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); signatureExponent = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading Signature... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(signature, 0, signature.Length); fireDebug(" Reading Padding... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(padding, 0, padding.Length); fireDebug(" Reading Issuer... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(issuer, 0, issuer.Length); fireDebug(" Reading Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading CA Crl Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Signer Crl Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Padding Byte... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); version = temp[0]; caCrlVersion = temp[1]; signerCrlVersion = temp[2]; paddingByte = temp[3]; fireDebug(" Reading Startup IOS... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 8); startupIos = Shared.Swap(BitConverter.ToUInt64(temp, 0)); fireDebug(" Reading Title ID... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 8); titleId = Shared.Swap(BitConverter.ToUInt64(temp, 0)); fireDebug(" Reading Title Type... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); titleType = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading Group ID... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 2); groupId = Shared.Swap(BitConverter.ToUInt16(temp, 0)); fireDebug(" Reading Padding2... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 2); padding2 = Shared.Swap(BitConverter.ToUInt16(temp, 0)); fireDebug(" Reading Region... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 2); region = Shared.Swap(BitConverter.ToUInt16(temp, 0)); fireDebug(" Reading Reserved... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(reserved, 0, reserved.Length); fireDebug(" Reading Access Rights... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); accessRights = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading Title Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading NumOfContents... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Boot Index... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Padding3... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 8); titleVersion = Shared.Swap(BitConverter.ToUInt16(temp, 0)); numOfContents = Shared.Swap(BitConverter.ToUInt16(temp, 2)); bootIndex = Shared.Swap(BitConverter.ToUInt16(temp, 4)); padding3 = Shared.Swap(BitConverter.ToUInt16(temp, 6)); contents = new List <TMD_Content>(); //Read Contents for (int i = 0; i < numOfContents; i++) { fireDebug(" Reading Content #{0} of {1}... (Offset: 0x{2})", i + 1, numOfContents, tmdFile.Position.ToString("x8").ToUpper().ToUpper()); TMD_Content tempContent = new TMD_Content(); tempContent.Hash = new byte[20]; tmdFile.Read(temp, 0, 8); tempContent.ContentID = Shared.Swap(BitConverter.ToUInt32(temp, 0)); tempContent.Index = Shared.Swap(BitConverter.ToUInt16(temp, 4)); tempContent.Type = (ContentType)Shared.Swap(BitConverter.ToUInt16(temp, 6)); tmdFile.Read(temp, 0, 8); tempContent.Size = Shared.Swap(BitConverter.ToUInt64(temp, 0)); tmdFile.Read(tempContent.Hash, 0, tempContent.Hash.Length); contents.Add(tempContent); } fireDebug("Pasing TMD Finished..."); }
/// <summary> /// Adds a TMD content. /// </summary> /// <param name="content"></param> public void AddContent(TMD_Content content) { contents.Add(content); numOfContents = (ushort)contents.Count; }
/// <summary> /// Adds a content to the WAD. /// </summary> /// <param name="newContent"></param> /// <param name="contentID"></param> /// <param name="index"></param> /// <param name="type"></param> public void AddContent(byte[] newContent, int contentID, int index, ContentType type = ContentType.Normal) { TMD_Content temp = new TMD_Content(); temp.ContentID = (uint)contentID; temp.Index = (ushort)index; temp.Type = type; temp.Size = (ulong)newContent.Length; temp.Hash = sha.ComputeHash(newContent); tmd.AddContent(temp); contents.Add(newContent); wadHeader.TmdSize = (uint)(484 + tmd.NumOfContents * 36); }
private void parseTmd(Stream tmdFile) { fireDebug("Pasing TMD..."); tmdFile.Seek(0, SeekOrigin.Begin); byte[] temp = new byte[8]; fireDebug(" Reading Signature Exponent... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); signatureExponent = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading Signature... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(signature, 0, signature.Length); fireDebug(" Reading Padding... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(padding, 0, padding.Length); fireDebug(" Reading Issuer... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(issuer, 0, issuer.Length); fireDebug(" Reading Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading CA Crl Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Signer Crl Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Padding Byte... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); version = temp[0]; caCrlVersion = temp[1]; signerCrlVersion = temp[2]; paddingByte = temp[3]; fireDebug(" Reading Startup IOS... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 8); startupIos = Shared.Swap(BitConverter.ToUInt64(temp, 0)); fireDebug(" Reading Title ID... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 8); titleId = Shared.Swap(BitConverter.ToUInt64(temp, 0)); fireDebug(" Reading Title Type... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); titleType = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading Group ID... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 2); groupId = Shared.Swap(BitConverter.ToUInt16(temp, 0)); fireDebug(" Reading Padding2... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 2); padding2 = Shared.Swap(BitConverter.ToUInt16(temp, 0)); fireDebug(" Reading Region... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 2); region = Shared.Swap(BitConverter.ToUInt16(temp, 0)); fireDebug(" Reading Reserved... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(reserved, 0, reserved.Length); fireDebug(" Reading Access Rights... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 4); accessRights = Shared.Swap(BitConverter.ToUInt32(temp, 0)); fireDebug(" Reading Title Version... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading NumOfContents... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Boot Index... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); fireDebug(" Reading Padding3... (Offset: 0x{0})", tmdFile.Position.ToString("x8").ToUpper()); tmdFile.Read(temp, 0, 8); titleVersion = Shared.Swap(BitConverter.ToUInt16(temp, 0)); numOfContents = Shared.Swap(BitConverter.ToUInt16(temp, 2)); bootIndex = Shared.Swap(BitConverter.ToUInt16(temp, 4)); padding3 = Shared.Swap(BitConverter.ToUInt16(temp, 6)); contents = new List<TMD_Content>(); //Read Contents for (int i = 0; i < numOfContents; i++) { fireDebug(" Reading Content #{0} of {1}... (Offset: 0x{2})", i + 1, numOfContents, tmdFile.Position.ToString("x8").ToUpper().ToUpper()); TMD_Content tempContent = new TMD_Content(); tempContent.Hash = new byte[20]; tmdFile.Read(temp, 0, 8); tempContent.ContentID = Shared.Swap(BitConverter.ToUInt32(temp, 0)); tempContent.Index = Shared.Swap(BitConverter.ToUInt16(temp, 4)); tempContent.Type = (ContentType)Shared.Swap(BitConverter.ToUInt16(temp, 6)); tmdFile.Read(temp, 0, 8); tempContent.Size = Shared.Swap(BitConverter.ToUInt64(temp, 0)); tmdFile.Read(tempContent.Hash, 0, tempContent.Hash.Length); contents.Add(tempContent); } fireDebug("Pasing TMD Finished..."); }
public void downloadTitle() { //fireDebug("Downloading Title {0} {1}...", mTitleId, mTitleVersion); // Create dirs if (!Directory.Exists(mOutputDir)) { Directory.CreateDirectory(mOutputDir); } //Download TMD fireDebug(" - TMD... "); TMD tmd = downloadTmd(); //fireDebug(" {0} Contents.\r\n", tmd.NumOfContents); mBytesTotal = 0; for (int i = 0; i < tmd.NumOfContents; i++) { mBytesTotal += (long)tmd.Contents[i].Size; } fireDebug(" Contents:" + tmd.NumOfContents + ", Size:" + ConvertUnit(mBytesTotal) + "\r\n"); fireDebug(" - Ticket..."); //Download cetk try { downloadTicket(); fireDebug(" OK! \r\n"); } catch (Exception ex) { fireDebug(" Fail! \r\n"); if (!mContinueWithoutTicket) { fireDebug(" + Downloading Ticket Failed..."); throw new Exception("Downloading Ticket Failed:\n" + ex.Message); } } string[] encryptedContents = new string[tmd.NumOfContents]; mBytesTotalDone = 0; //Download Content for (int i = 0; i < tmd.NumOfContents; i++) { TMD_Content content = tmd.Contents[i]; fireDebug(" - Content:[{0}/{1}], ID:{2}, Size:{3} ...", i + 1, tmd.NumOfContents, content.ContentID.ToString("x8"), ConvertUnit((long)content.Size)); fireTotalProgress(mBytesTotalDone, mBytesTotal); downloadContent(content); if (!cancelDownload) { mBytesTotalDone += (long)tmd.Contents[i].Size; fireTotalProgress(mBytesTotalDone, mBytesTotal); fireDebug(" OK! \r\n"); } else { fireDebug("Canceled!\r\n"); throw new OperationCanceledException(); } } // Create cert file createCert(); }