public ModifiableNintendoSubmissionPackageArchive(IReadableSink outSink, NintendoSubmissionPackageReader nspReader, ISource inSource, string targetEntryPath, string descFilePath, KeyConfiguration keyConfig) { this.m_KeyConfig = keyConfig; NintendoSubmissionPackageFileSystemInfo replacedNspInfo = ArchiveReconstructionUtils.GetReplacedNspInfo(nspReader, inSource, targetEntryPath, descFilePath, this.m_KeyConfig); this.ConnectionList = new List <Connection>((IEnumerable <Connection>) new NintendoSubmissionPackageArchive(outSink, replacedNspInfo, this.m_KeyConfig).ConnectionList); }
public ProdEncryptedNintendoSubmissionPackageArchive(IReadableSink outSink, NintendoSubmissionPackageReader nspReader, KeyConfiguration keyConfig, DebugConfiguration debugConfig) { this.m_KeyConfig = keyConfig; NintendoSubmissionPackageFileSystemInfo prodNspInfo = ArchiveReconstructionUtils.GetProdNspInfo(nspReader, this.m_KeyConfig); prodNspInfo.EnableContentMetaBinaryExport = debugConfig.EnableContentMetaBinaryExport; this.ConnectionList = new List <Connection>((IEnumerable <Connection>) new NintendoSubmissionPackageArchive(outSink, prodNspInfo, this.m_KeyConfig).ConnectionList); }
private static ModelType ReadXml <ModelType>(NintendoSubmissionPackageReader nspReader, string fileName, long fileSize) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(ModelType)); using (MemoryStream memoryStream = new MemoryStream((int)fileSize)) { byte[] buffer = nspReader.ReadFile(fileName, 0L, fileSize); memoryStream.Write(buffer, 0, buffer.Length); memoryStream.Seek(0L, SeekOrigin.Begin); return((ModelType)xmlSerializer.Deserialize((Stream)memoryStream)); } }
internal static void List(Option option) { byte[][] areaEncryptionKeys = option.Config.GetKeyConfiguration().GetKeyAreaEncryptionKeys(); using (FileStream fileStream = Program.OpenReadOnlyFileStream(option.List.InputFile, FileOptions.SequentialScan)) { string fileName1 = Path.GetFileName(option.List.InputFile); if (Path.GetExtension(fileName1) == ".nsp") { NintendoSubmissionPackageReader submissionPackageReader = new NintendoSubmissionPackageReader((Stream)fileStream); foreach (Tuple <string, long> tuple in submissionPackageReader.ListFileInfo()) { Console.WriteLine("{0, -45}\t({1} byte)", (object)tuple.Item1, (object)tuple.Item2); } Console.WriteLine("---------------------------------------------"); foreach (Tuple <string, long> tuple in submissionPackageReader.ListFileInfo().FindAll((Predicate <Tuple <string, long> >)(x => Path.GetExtension(x.Item1) == ".nca"))) { string str = tuple.Item1; long num = tuple.Item2; Program.ListNca(submissionPackageReader.OpenNintendoContentArchiveReader(str, areaEncryptionKeys), str); } } else if (Path.GetExtension(fileName1) == ".nca") { Program.ListNca(new NintendoContentArchiveReader((Stream)fileStream, areaEncryptionKeys), (string)null); } else { if (!(Path.GetExtension(fileName1) == ".xci") && !(Path.GetExtension(fileName1) == ".xcie")) { throw new ArgumentException("input archive file must be .nca or .nsp file."); } Console.WriteLine("[headerInfo]"); long offset1 = (long)XciInfo.CardKeyAreaPageCount * (long)XciInfo.PageSize; SubStream subStream = new SubStream((Stream)fileStream, offset1, (long)XciInfo.CardHeaderPageCount * (long)XciInfo.PageSize); byte[] numArray = new byte[subStream.Length]; subStream.Read(numArray, 0, (int)subStream.Length); XciUtils.DumpHeader(numArray); long offset2 = (long)XciInfo.NormalAreaStartPageAddress * (long)XciInfo.PageSize; XciReader xciReader = new XciReader((Stream) new SubStream((Stream)fileStream, offset2, fileStream.Length - offset2)); foreach (Tuple <string, long> tuple1 in xciReader.ListFileInfo()) { string fileName2 = tuple1.Item1; XciPartitionReader xciPartitionReader = xciReader.OpenXciPartitionReader(fileName2); Console.WriteLine("[{0}]", (object)fileName2); foreach (Tuple <string, long> tuple2 in xciPartitionReader.ListFileInfo()) { Console.WriteLine("{0, -45}\t({1} byte)", (object)tuple2.Item1, (object)tuple2.Item2); } } } } }
internal static NintendoSubmissionPackageFileSystemInfo GetProdNspInfo(NintendoSubmissionPackageReader nspReader, KeyConfiguration keyConfig) { ArchiveReconstructionUtils.GetContentInfoDelegate getContentInfoImpl = (ArchiveReconstructionUtils.GetContentInfoDelegate)(contentInfo => new NintendoSubmissionPackageFileSystemInfo.ContentInfo() { FsInfo = (Nintendo.Authoring.FileSystemMetaLibrary.FileSystemInfo)ArchiveReconstructionUtils.GetProdNcaInfo(nspReader.OpenNintendoContentArchiveReader(contentInfo.Id + ".nca", keyConfig.GetKeyAreaEncryptionKeys())), ContentType = contentInfo.Type }); ArchiveReconstructionUtils.GetContentMetaInfoDelegate getContentMetaInfoImpl = (ArchiveReconstructionUtils.GetContentMetaInfoDelegate)((ref NintendoSubmissionPackageFileSystemInfo.EntryInfo entry, string contentMetaFileName, ContentMetaModel model) => ArchiveReconstructionUtils.GetCommonContentMetaInfo(ref entry, contentMetaFileName, model, nspReader, keyConfig)); NintendoSubmissionPackageFileSystemInfo nspInfo = ArchiveReconstructionUtils.GetNspInfo(nspReader, keyConfig, getContentInfoImpl, getContentMetaInfoImpl); nspInfo.IsProdEncryption = true; return(nspInfo); }
public static void ProdEncryptNintendoSubmissionPackageArchiveForXci(Stream outStream, Stream outXmlStream, Stream inStream, Stream inUppStream, Stream inPatchStream, byte launchFlags, AuthoringConfiguration config) { try { SourceSinkDriver sourceSinkDriver = new SourceSinkDriver(); NintendoSubmissionPackageReader uppReader = inUppStream != null ? new NintendoSubmissionPackageReader(inUppStream) : (NintendoSubmissionPackageReader)null; sourceSinkDriver.Add((IConnector) new ProdEncryptedXciArchive((IReadableSink) new StreamSink(outStream), new NintendoSubmissionPackageReader(inStream), uppReader, (NintendoSubmissionPackageReader)null, launchFlags, config.GetKeyConfiguration())); sourceSinkDriver.Run(); } catch (Exception ex) { new ResultXmlGenerator(ex.Message + Environment.NewLine + ex.StackTrace).WriteToStream(outXmlStream); throw; } }
internal static void ExtractNsp(Option option) { using (FileStream fileStream = Program.OpenReadOnlyFileStream(option.ExtractNsp.InputNspFile, FileOptions.SequentialScan)) { NintendoSubmissionPackageReader submissionPackageReader = new NintendoSubmissionPackageReader((Stream)fileStream); foreach (Tuple <string, long> tuple in submissionPackageReader.ListFileInfo()) { string fileName = tuple.Item1; long fileSize = tuple.Item2; string extractedPath = option.ExtractNsp.OutputDirectory + "/" + fileName; Console.WriteLine("Extracting {0}.", (object)extractedPath); Program.FsUtil.WriteFile((IFileSystemArchiveReader)submissionPackageReader, extractedPath, fileName, fileSize); } } }
public ResultXmlGenerator(Stream stream, bool isXci) { ResultModel model = new ResultModel(); model.Code = "Pass"; model.ErrorMessage = string.Empty; model.Size = stream.Length; SHA256CryptoServiceProvider cryptoServiceProvider = new SHA256CryptoServiceProvider(); stream.Seek(0L, SeekOrigin.Begin); model.SetHashBytes(cryptoServiceProvider.ComputeHash(stream)); if (!isXci) { NintendoSubmissionPackageReader submissionPackageReader = new NintendoSubmissionPackageReader(stream); foreach (Tuple <string, long> tuple in submissionPackageReader.ListFileInfo()) { string fileName = tuple.Item1; long size = tuple.Item2; if (fileName.EndsWith(".cnmt.xml")) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(ContentMetaModel)); ContentMetaModel contentMetaModel; using (MemoryStream memoryStream = new MemoryStream((int)size)) { byte[] buffer = submissionPackageReader.ReadFile(fileName, 0L, size); memoryStream.Write(buffer, 0, buffer.Length); memoryStream.Seek(0L, SeekOrigin.Begin); contentMetaModel = (ContentMetaModel)xmlSerializer.Deserialize((Stream)memoryStream); } model.ContentMetaList.Add(contentMetaModel); } } } this.SetCommon(ref model); this.m_model = model; }
internal static NintendoSubmissionPackageFileSystemInfo GetReplacedNspInfo(NintendoSubmissionPackageReader nspReader, ISource inSource, string targetEntryPath, string descFilePath, KeyConfiguration keyConfig) { bool isReplaced = false; ArchiveReconstructionUtils.GetContentInfoDelegate getContentInfoImpl = (ArchiveReconstructionUtils.GetContentInfoDelegate)(contentInfo => { NintendoSubmissionPackageFileSystemInfo.ContentInfo contentInfo1 = new NintendoSubmissionPackageFileSystemInfo.ContentInfo(); string fileName = contentInfo.Id + ".nca"; NintendoContentArchiveReader ncaReader = nspReader.OpenNintendoContentArchiveReader(fileName, keyConfig.GetKeyAreaEncryptionKeys()); if (targetEntryPath.StartsWith(fileName)) { contentInfo1.FsInfo = (Nintendo.Authoring.FileSystemMetaLibrary.FileSystemInfo)ArchiveReconstructionUtils.GetReplacedNcaInfo(ncaReader, descFilePath, new EntryReplaceRule() { Source = inSource, Path = targetEntryPath.Substring(fileName.Length + 1) }); isReplaced = true; } else { contentInfo1.Source = (ISource) new FileSystemArchvieFileSource((IFileSystemArchiveReader)nspReader, fileName); } contentInfo1.ContentType = contentInfo.Type; return(contentInfo1); }); ArchiveReconstructionUtils.GetContentMetaInfoDelegate getContentMetaInfoImpl = (ArchiveReconstructionUtils.GetContentMetaInfoDelegate)((ref NintendoSubmissionPackageFileSystemInfo.EntryInfo entry, string contentMetaFileName, ContentMetaModel model) => { ArchiveReconstructionUtils.GetCommonContentMetaInfo(ref entry, contentMetaFileName, model, nspReader, keyConfig); if (!targetEntryPath.StartsWith(contentMetaFileName) || !targetEntryPath.EndsWith(".cnmt")) { return; } NintendoContentMetaReader contentMetaReader1 = new NintendoContentMetaReader(entry.ContentMetaInfo.Data); ulong id1 = contentMetaReader1.GetId(); uint version1 = contentMetaReader1.GetVersion(); if (inSource.Size != (long)entry.ContentMetaInfo.Data.Length) { throw new Exception(".cnmt file specified to be replaced is invalid."); } ByteData byteData = inSource.PullData(0L, (int)inSource.Size); ArraySegment <byte> buffer = byteData.Buffer; byte[] array = buffer.Array; buffer = byteData.Buffer; int offset = buffer.Offset; byte[] data = entry.ContentMetaInfo.Data; int dstOffset = 0; int count = byteData.Buffer.Count; Buffer.BlockCopy((Array)array, offset, (Array)data, dstOffset, count); NintendoContentMetaReader contentMetaReader2 = new NintendoContentMetaReader(entry.ContentMetaInfo.Data); ulong id2 = contentMetaReader2.GetId(); if ((long)id1 != (long)id2) { throw new ArgumentException(string.Format("Ids of content meta are different. (oldId = {0:x16}, newID = {0:x16})", (object)id1, (object)id2)); } uint version2 = contentMetaReader2.GetVersion(); Log.Info(string.Format("content meta (ID = {0:x16}) will be replaced : version {1} -> {2}", (object)id1, (object)version1, (object)version2)); isReplaced = true; }); NintendoSubmissionPackageFileSystemInfo nspInfo = ArchiveReconstructionUtils.GetNspInfo(nspReader, keyConfig, getContentInfoImpl, getContentMetaInfoImpl); if (isReplaced) { return(nspInfo); } throw new Exception("nothing was replaced."); }
private static NintendoSubmissionPackageFileSystemInfo GetNspInfo(NintendoSubmissionPackageReader nspReader, KeyConfiguration keyConfig, ArchiveReconstructionUtils.GetContentInfoDelegate getContentInfoImpl, ArchiveReconstructionUtils.GetContentMetaInfoDelegate getContentMetaInfoImpl) { NintendoSubmissionPackageFileSystemInfo packageFileSystemInfo = new NintendoSubmissionPackageFileSystemInfo(); packageFileSystemInfo.Version = (byte)0; foreach (Tuple <string, long> tuple in nspReader.ListFileInfo()) { string fileName = tuple.Item1; long fileSize = tuple.Item2; if (fileName.EndsWith(".cnmt.xml")) { ContentMetaModel model = ArchiveReconstructionUtils.ReadXml <ContentMetaModel>(nspReader, fileName, fileSize); string type = model.Type; if (!(type == "Application")) { if (!(type == "Patch")) { if (type == "AddOnContent") { model = (ContentMetaModel)ArchiveReconstructionUtils.ReadXml <AddOnContentContentMetaModel>(nspReader, fileName, fileSize); } } else { model = (ContentMetaModel)ArchiveReconstructionUtils.ReadXml <PatchContentMetaModel>(nspReader, fileName, fileSize); } } else { model = (ContentMetaModel)ArchiveReconstructionUtils.ReadXml <ApplicationContentMetaModel>(nspReader, fileName, fileSize); } NintendoSubmissionPackageFileSystemInfo.EntryInfo entry = new NintendoSubmissionPackageFileSystemInfo.EntryInfo(); entry.Contents = new List <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); foreach (ContentModel content in model.ContentList) { if (!(content.Type == "Meta")) { NintendoSubmissionPackageFileSystemInfo.ContentInfo contentInfo = getContentInfoImpl(content); entry.Contents.Add(contentInfo); } } string contentMetaFileName = Path.GetFileNameWithoutExtension(fileName) + ".nca"; getContentMetaInfoImpl(ref entry, contentMetaFileName, model); List <NintendoSubmissionPackageExtraData> list = nspReader.ListFileInfo().FindAll((Predicate <Tuple <string, long> >)(x => { if (x.Item1.StartsWith(fileName.Replace(".cnmt.xml", ""))) { return(x.Item1.EndsWith(".jpg")); } return(false); })).Select <Tuple <string, long>, NintendoSubmissionPackageExtraData>((Func <Tuple <string, long>, NintendoSubmissionPackageExtraData>)(x => { byte[] buffer = nspReader.ReadFile(x.Item1, 0L, x.Item2); return(new NintendoSubmissionPackageExtraData(x.Item1, (ISource) new MemorySource(buffer, 0, buffer.Length))); })).ToList <NintendoSubmissionPackageExtraData>(); entry.ExtraData = list; packageFileSystemInfo.Entries.Add(entry); } if (fileName == "cardspec.xml") { CardSpecModel cardSpecModel = ArchiveReconstructionUtils.ReadXml <CardSpecModel>(nspReader, fileName, fileSize); packageFileSystemInfo.CardSize = Convert.ToInt32(cardSpecModel.Size, 10); packageFileSystemInfo.CardClockRate = Convert.ToInt32(cardSpecModel.ClockRate, 10); } } return(packageFileSystemInfo); }
private static void GetCommonContentMetaInfo(ref NintendoSubmissionPackageFileSystemInfo.EntryInfo entry, string contentMetaFileName, ContentMetaModel model, NintendoSubmissionPackageReader nspReader, KeyConfiguration keyConfig) { IFileSystemArchiveReader systemArchiveReader = nspReader.OpenNintendoContentArchiveReader(contentMetaFileName, keyConfig.GetKeyAreaEncryptionKeys()).OpenFileSystemArchiveReader(0); Tuple <string, long> tuple = systemArchiveReader.ListFileInfo().Single <Tuple <string, long> >(); entry.ContentMetaInfo = new NintendoSubmissionPackageFileSystemInfo.ContentMetaInfo(systemArchiveReader.ReadFile(tuple.Item1, 0L, tuple.Item2), model); NintendoContentMetaReader contentMetaReader = new NintendoContentMetaReader(entry.ContentMetaInfo.Data); entry.MetaType = contentMetaReader.GetType(); }
internal static void Extract(Option option) { byte[][] areaEncryptionKeys = option.Config.GetKeyConfiguration().GetKeyAreaEncryptionKeys(); bool flag1 = false; bool flag2 = !string.IsNullOrEmpty(option.Extract.TargetEntryPath); string outputDirectory = option.Extract.OutputDirectory; string targetEntryPath1 = option.Extract.TargetEntryPath; string fileName = Path.GetFileName(option.Extract.InputFile); try { Directory.CreateDirectory(outputDirectory); using (FileStream fileStream = Program.OpenReadOnlyFileStream(option.Extract.InputFile, FileOptions.SequentialScan)) { if (Path.GetExtension(fileName) == ".nsp") { NintendoSubmissionPackageReader submissionPackageReader = new NintendoSubmissionPackageReader((Stream)fileStream); foreach (Tuple <string, long> tuple in submissionPackageReader.ListFileInfo()) { string str1 = tuple.Item1; long fileSize = tuple.Item2; if (!Program.FsUtil.CheckShouldSkipStartsWithPath(targetEntryPath1, str1)) { string extractedPath = Path.Combine(outputDirectory, str1); if (Path.GetExtension(str1) == ".nca") { Console.WriteLine("Target: {0}\t({1} byte)", (object)str1, (object)fileSize); if (targetEntryPath1 == str1) { Program.FsUtil.WriteFile((IFileSystemArchiveReader)submissionPackageReader, extractedPath, str1, fileSize); flag1 = true; break; } NintendoContentArchiveReader reader = submissionPackageReader.OpenNintendoContentArchiveReader(str1, areaEncryptionKeys); string str2 = flag2 ? outputDirectory : extractedPath; string str3 = flag2 ? targetEntryPath1.Substring(str1.Length + 1) : targetEntryPath1; string outputDirectoryPath = str2; string targetEntryPath2 = str3; Program.ExtractNca(reader, outputDirectoryPath, targetEntryPath2); flag1 = true; } else { Console.WriteLine("Extracting {0}\t({1} byte)", (object)str1, (object)fileSize); Program.FsUtil.WriteFile((IFileSystemArchiveReader)submissionPackageReader, extractedPath, str1, fileSize); flag1 = true; } } } } else { if (!(Path.GetExtension(fileName) == ".nca")) { throw new ArgumentException("input archive file must be .nca or .nsp file."); } Program.ExtractNca(new NintendoContentArchiveReader((Stream)fileStream, areaEncryptionKeys), outputDirectory, targetEntryPath1); flag1 = true; } } } catch (ExtractEntryNotFoundException ex) { } if (flag1) { return; } if (!string.IsNullOrEmpty(option.Extract.OutputDirectory)) { Console.Error.WriteLine("[Error] Target entry path '{0}' not found.", (object)option.Extract.TargetEntryPath); } else { Console.Error.WriteLine("[Error] Nothing to be extracted."); } }
public ProdEncryptedXciArchive(IReadableSink outSink, NintendoSubmissionPackageReader nspReader, NintendoSubmissionPackageReader uppReader, NintendoSubmissionPackageReader patchReader, byte launchFlags, KeyConfiguration keyConfig) { this.ConnectionList = new List <Connection>(); this.m_rng = new RNGCryptoServiceProvider(); this.m_keyConfig = keyConfig; this.SetCryptor(this.m_keyConfig); uint num1 = 0; uint num2 = 0; ulong num3 = 0; byte[] numArray1 = (byte[])null; NintendoSubmissionPackageFileSystemInfo prodNspInfo = ArchiveReconstructionUtils.GetProdNspInfo(nspReader, this.m_keyConfig); XciUtils.CheckRomSizeAndClockRate(prodNspInfo.CardSize, prodNspInfo.CardClockRate); NintendoSubmissionPackageFileSystemInfo uppInfo = (NintendoSubmissionPackageFileSystemInfo)null; if (uppReader != null) { uppInfo = ArchiveReconstructionUtils.GetProdNspInfo(uppReader, this.m_keyConfig); } XciSizeInfo xciSize = ProdEncryptedXciArchive.CalculateXciSize(prodNspInfo, uppInfo, (NintendoSubmissionPackageFileSystemInfo)null, this.m_keyConfig); int romSize = XciUtils.GetRomSize(xciSize.TotalSize); if (romSize == XciInfo.InvalidRomSize) { throw new ArgumentException(string.Format("Xci size exceed the maximum size of the game card.", Array.Empty <object>())); } if (prodNspInfo.CardSize < romSize) { throw new ArgumentException(string.Format("Xci requires CardSpec/Size = {0}, though it is set as {1}.", (object)romSize, (object)prodNspInfo.CardSize)); } outSink.SetSize(xciSize.TotalSize); List <Sha256PartitionFsHashSource> hashSources1 = new List <Sha256PartitionFsHashSource>(); PartitionFileSystemInfo partFsInfo1 = new PartitionFileSystemInfo(); List <ContentHashSource> hashSources2 = new List <ContentHashSource>(); List <Sha256PartitionFsHashSource> hashSources3 = new List <Sha256PartitionFsHashSource>(); if (uppInfo != null && uppReader != null) { long partitionHeaderSize = xciSize.UpdatePartitionHeaderSize; foreach (NintendoSubmissionPackageFileSystemInfo.EntryInfo entry in uppInfo.Entries) { if (entry.MetaType == "SystemUpdate") { NintendoContentMetaReader contentMetaReader = new NintendoContentMetaReader(entry.ContentMetaInfo.Data); num2 = contentMetaReader.GetVersion(); num3 = contentMetaReader.GetId(); } } byte[] buffer = uppReader.ReadBase(0L, uppReader.GetBaseSize()); numArray1 = new SHA256CryptoServiceProvider().ComputeHash(buffer, 0, buffer.Length); foreach (Tuple <string, long> tuple in uppReader.ListFileInfo().FindAll((Predicate <Tuple <string, long> >)(x => x.Item1.EndsWith(".nca")))) { string str = tuple.Item1; long num4 = tuple.Item2; ulong offset = (ulong)(partitionHeaderSize - xciSize.UpdatePartitionHeaderSize); PartitionFileSystemInfo.EntryInfo entryInfo = PartitionFileSystemInfo.EntryInfo.Make(str, (ulong)num4, offset, 0UL, XciInfo.PageSize); partFsInfo1.entries.Add(entryInfo); FileSystemArchvieFileSource archvieFileSource = new FileSystemArchvieFileSource((IFileSystemArchiveReader)uppReader, str); IReadableSink readableSink = (IReadableSink) new ReadableSubSink(outSink, xciSize.UpdatePartitionOffset + partitionHeaderSize, archvieFileSource.Size); this.ConnectionList.Add(new Connection((ISource)archvieFileSource, (ISink)readableSink)); hashSources2.Add(new ContentHashSource((ISource)null, "no_change")); SinkLinkedSource sinkLinkedSource = new SinkLinkedSource((ISink)readableSink, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink.ToSource(), 0L, (long)XciInfo.PageSize))); hashSources3.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource, hashSources3.Count)); partitionHeaderSize += archvieFileSource.Size; } } HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource1 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources2, partFsInfo1, xciSize.UpdatePartitionHeaderSize), hashSources3); IReadableSink readableSink1 = (IReadableSink) new ReadableSubSink(outSink, xciSize.UpdatePartitionOffset, partitionFsHeaderSource1.Size); this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource1, (ISink)readableSink1)); SinkLinkedSource sinkLinkedSource1 = new SinkLinkedSource((ISink)readableSink1, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink1.ToSource(), 0L, xciSize.UpdatePartitionHeaderSize))); hashSources1.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource1, hashSources1.Count)); PartitionFileSystemInfo partFsInfo2 = new PartitionFileSystemInfo(); PartitionFileSystemInfo partFsInfo3 = new PartitionFileSystemInfo(); List <ContentHashSource> hashSources4 = new List <ContentHashSource>(); List <ContentHashSource> hashSources5 = new List <ContentHashSource>(); List <Sha256PartitionFsHashSource> hashSources6 = new List <Sha256PartitionFsHashSource>(); List <Sha256PartitionFsHashSource> hashSources7 = new List <Sha256PartitionFsHashSource>(); long partitionHeaderSize1 = xciSize.SecurePartitionHeaderSize; long partitionHeaderSize2 = xciSize.NormalPartitionHeaderSize; for (int index1 = 0; index1 < prodNspInfo.Entries.Count; ++index1) { NintendoSubmissionPackageFileSystemInfo.EntryInfo entry = prodNspInfo.Entries[index1]; List <Tuple <ISource, NintendoContentInfo> > contentSourceList = new List <Tuple <ISource, NintendoContentInfo> >(); for (int index2 = 0; index2 < entry.Contents.Count; ++index2) { NintendoSubmissionPackageFileSystemInfo.ContentInfo content = entry.Contents[index2]; if (!(content.ContentType == "Meta")) { if (content.ContentType == "Program") { num1 = (content.FsInfo as NintendoContentFileSystemInfo).sdkAddonVersion; } (content.FsInfo as NintendoContentFileSystemInfo).distributionType = (byte)1; NintendoContentArchiveSource contentArchiveSource = new NintendoContentArchiveSource(content.FsInfo as NintendoContentFileSystemInfo, this.m_keyConfig, false); ulong offset1 = (ulong)(partitionHeaderSize1 - xciSize.SecurePartitionHeaderSize); PartitionFileSystemInfo.EntryInfo entryInfo1 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.nca", (ulong)contentArchiveSource.Size, offset1, 0UL, XciInfo.PageSize); partFsInfo2.entries.Add(entryInfo1); IReadableSink readableSink2 = (IReadableSink) new ReadableSubSink(outSink, xciSize.SecurePartitionOffset + partitionHeaderSize1, contentArchiveSource.Size); this.ConnectionList.Add(new Connection((ISource)contentArchiveSource, (ISink)readableSink2)); SinkLinkedSource sinkLinkedSource2 = new SinkLinkedSource((ISink)readableSink2, (ISource) new Sha256StreamHashSource(readableSink2.ToSource())); SinkLinkedSource sinkLinkedSource3 = new SinkLinkedSource((ISink)readableSink2, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink2.ToSource(), 0L, (long)XciInfo.PageSize))); hashSources4.Add(new ContentHashSource((ISource)sinkLinkedSource2, ".nca")); hashSources6.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource3, hashSources6.Count)); contentSourceList.Add(Tuple.Create <ISource, NintendoContentInfo>(hashSources4[hashSources4.Count - 1].Source, new NintendoContentInfo(content.ContentType, contentArchiveSource.Size))); partitionHeaderSize1 += ProdEncryptedXciArchive.RoundupPageSize(contentArchiveSource.Size); if (content.ContentType == "Control") { ulong offset2 = (ulong)(partitionHeaderSize2 - xciSize.NormalPartitionHeaderSize); PartitionFileSystemInfo.EntryInfo entryInfo2 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.nca", (ulong)contentArchiveSource.Size, offset2, 0UL, XciInfo.PageSize); partFsInfo3.entries.Add(entryInfo2); SinkLinkedSource sinkLinkedSource4 = new SinkLinkedSource((ISink)readableSink2, readableSink2.ToSource()); IReadableSink readableSink3 = (IReadableSink) new ReadableSubSink(outSink, xciSize.NormalPartitionOffset + partitionHeaderSize2, sinkLinkedSource4.Size); this.ConnectionList.Add(new Connection((ISource)sinkLinkedSource4, (ISink)readableSink3)); hashSources5.Add(new ContentHashSource((ISource)sinkLinkedSource2, ".nca")); hashSources7.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource3, hashSources7.Count)); partitionHeaderSize2 += ProdEncryptedXciArchive.RoundupPageSize(contentArchiveSource.Size); } } } NintendoContentMetaArchiveSource metaArchiveSource = new NintendoContentMetaArchiveSource(new NintendoContentMetaBase(contentSourceList, entry.ContentMetaInfo.Data, entry.ContentMetaInfo.Model, true), entry.KeyIndex, this.m_keyConfig, prodNspInfo.IsProdEncryption, true); ulong offset3 = (ulong)(partitionHeaderSize1 - xciSize.SecurePartitionHeaderSize); PartitionFileSystemInfo.EntryInfo entryInfo3 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cnmt.nca", (ulong)metaArchiveSource.Size, offset3, 0UL, XciInfo.PageSize); partFsInfo2.entries.Add(entryInfo3); IReadableSink readableSink4 = (IReadableSink) new ReadableSubSink(outSink, xciSize.SecurePartitionOffset + partitionHeaderSize1, metaArchiveSource.Size); this.ConnectionList.Add(new Connection((ISource)metaArchiveSource, (ISink)readableSink4)); SinkLinkedSource sinkLinkedSource5 = new SinkLinkedSource((ISink)readableSink4, (ISource) new Sha256StreamHashSource(readableSink4.ToSource())); SinkLinkedSource sinkLinkedSource6 = new SinkLinkedSource((ISink)readableSink4, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink4.ToSource(), 0L, (long)XciInfo.PageSize))); hashSources4.Add(new ContentHashSource((ISource)sinkLinkedSource5, ".cnmt.nca")); hashSources6.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource6, hashSources6.Count)); partitionHeaderSize1 += ProdEncryptedXciArchive.RoundupPageSize(metaArchiveSource.Size); ulong offset4 = (ulong)(partitionHeaderSize2 - xciSize.NormalPartitionHeaderSize); PartitionFileSystemInfo.EntryInfo entryInfo4 = PartitionFileSystemInfo.EntryInfo.Make("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.cnmt.nca", (ulong)metaArchiveSource.Size, offset4, 0UL, XciInfo.PageSize); partFsInfo3.entries.Add(entryInfo4); SinkLinkedSource sinkLinkedSource7 = new SinkLinkedSource((ISink)readableSink4, readableSink4.ToSource()); IReadableSink readableSink5 = (IReadableSink) new ReadableSubSink(outSink, xciSize.NormalPartitionOffset + partitionHeaderSize2, sinkLinkedSource7.Size); this.ConnectionList.Add(new Connection((ISource)sinkLinkedSource7, (ISink)readableSink5)); hashSources5.Add(new ContentHashSource((ISource)sinkLinkedSource5, ".cnmt.nca")); hashSources7.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource6, hashSources7.Count)); partitionHeaderSize2 += ProdEncryptedXciArchive.RoundupPageSize(metaArchiveSource.Size); } HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource2 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources5, partFsInfo3, xciSize.NormalPartitionHeaderSize), hashSources7); IReadableSink readableSink6 = (IReadableSink) new ReadableSubSink(outSink, xciSize.NormalPartitionOffset, partitionFsHeaderSource2.Size); this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource2, (ISink)readableSink6)); SinkLinkedSource sinkLinkedSource8 = new SinkLinkedSource((ISink)readableSink6, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink6.ToSource(), 0L, xciSize.NormalPartitionHeaderSize))); hashSources1.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource8, hashSources1.Count)); HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource3 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources4, partFsInfo2, xciSize.SecurePartitionHeaderSize), hashSources6); IReadableSink readableSink7 = (IReadableSink) new ReadableSubSink(outSink, xciSize.SecurePartitionOffset, partitionFsHeaderSource3.Size); this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource3, (ISink)readableSink7)); SinkLinkedSource sinkLinkedSource9 = new SinkLinkedSource((ISink)readableSink7, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink7.ToSource(), 0L, xciSize.SecurePartitionHeaderSize))); hashSources1.Add(new Sha256PartitionFsHashSource((ISource)sinkLinkedSource9, hashSources1.Count)); PartitionFileSystemInfo partFsInfo4 = new PartitionFileSystemInfo(); List <ContentHashSource> hashSources8 = new List <ContentHashSource>(); ulong offset5 = (ulong)(xciSize.UpdatePartitionOffset - xciSize.UpdatePartitionOffset); PartitionFileSystemInfo.EntryInfo entryInfo5 = PartitionFileSystemInfo.EntryInfo.Make("update", (ulong)(xciSize.UpdatePartitionHeaderSize + xciSize.UpdatePartitionSize), offset5, 0UL, (uint)xciSize.UpdatePartitionHeaderSize); partFsInfo4.entries.Add(entryInfo5); hashSources8.Add(new ContentHashSource((ISource)null, "update")); ulong offset6 = (ulong)(xciSize.NormalPartitionOffset - xciSize.UpdatePartitionOffset); PartitionFileSystemInfo.EntryInfo entryInfo6 = PartitionFileSystemInfo.EntryInfo.Make("normal", (ulong)(xciSize.NormalPartitionHeaderSize + xciSize.NormalPartitionSize), offset6, 0UL, (uint)xciSize.NormalPartitionHeaderSize); partFsInfo4.entries.Add(entryInfo6); hashSources8.Add(new ContentHashSource((ISource)null, "normal")); ulong offset7 = (ulong)(xciSize.SecurePartitionOffset - xciSize.UpdatePartitionOffset); PartitionFileSystemInfo.EntryInfo entryInfo7 = PartitionFileSystemInfo.EntryInfo.Make("secure", (ulong)(xciSize.SecurePartitionHeaderSize + xciSize.SecurePartitionSize), offset7, 0UL, (uint)xciSize.SecurePartitionHeaderSize); partFsInfo4.entries.Add(entryInfo7); hashSources8.Add(new ContentHashSource((ISource)null, "secure")); HashAdaptedSha256PartitionFsHeaderSource partitionFsHeaderSource4 = new HashAdaptedSha256PartitionFsHeaderSource((ISource) new HashNameEntryPartitionFsHeaderSource <Sha256PartitionFileSystemMeta>(hashSources8, partFsInfo4, xciSize.RootPartitionHeaderSize), hashSources1); IReadableSink readableSink8 = (IReadableSink) new ReadableSubSink(outSink, xciSize.RootPartitionOffset, partitionFsHeaderSource4.Size); this.ConnectionList.Add(new Connection((ISource)partitionFsHeaderSource4, (ISink)readableSink8)); ISource rootPartitionFsHeaderHashSource = (ISource) new SinkLinkedSource((ISink)readableSink8, (ISource) new Sha256StreamHashSource((ISource) new SubSource(readableSink8.ToSource(), 0L, xciSize.RootPartitionHeaderSize))); byte[] data1 = new byte[8]; this.m_rng.GetBytes(data1); ulong uint64 = BitConverter.ToUInt64(data1, 0); byte[] numArray2 = new byte[XciMeta.TitleKey1Size]; byte[] numArray3 = new byte[XciMeta.TitleKey2Size]; this.m_rng.GetBytes(numArray2); this.m_rng.GetBytes(numArray3); byte[] initialData = this.CreateInitialData(uint64, new Pair <byte[], byte[]>(numArray2, numArray3)); byte[] keyArea = this.CreateKeyArea(initialData, new Pair <byte[], byte[]>(numArray2, numArray3)); MemorySource memorySource = new MemorySource(keyArea, 0, keyArea.Length); byte[] data2 = new byte[XciInfo.IvSize]; this.m_rng.GetBytes(data2); XciInfo xciInfo = new XciInfo(); xciInfo.romAreaStartPageAddress = (uint)((ulong)xciSize.SecurePartitionOffset / (ulong)XciInfo.PageSize) - XciInfo.CardKeyAreaPageCount; xciInfo.kekIndex = XciInfo.KekIndexVersion0; xciInfo.romSize = XciInfo.ConvertRomSizeToRomSizeByte(prodNspInfo.CardSize); xciInfo.flags = launchFlags; xciInfo.packageId = uint64; xciInfo.validDataEndAddress = (uint)((int)(uint)((ulong)ProdEncryptedXciArchive.RoundupPageSize(xciSize.TotalSize) / (ulong)XciInfo.PageSize) - (int)XciInfo.CardKeyAreaPageCount - 1); xciInfo.iv = data2; xciInfo.partitionFsHeaderAddress = (ulong)(XciInfo.NormalAreaStartPageAddress - XciInfo.CardKeyAreaPageCount) * (ulong)XciInfo.PageSize; xciInfo.partitionFsHeaderSize = (ulong)xciSize.RootPartitionHeaderSize; xciInfo.partitionFsHeaderHash = (byte[])null; xciInfo.selSec = XciInfo.SelSecForT1; xciInfo.fwVersion = XciInfo.FwVersion; xciInfo.accCtrl1 = XciInfo.ConvertClockRateToAccCtrl1(prodNspInfo.CardClockRate); xciInfo.fwMode = num1; xciInfo.cupVersion = num2; xciInfo.cupId = num3; xciInfo.uppHash = numArray1 != null ? ((IEnumerable <byte>)numArray1).Take <byte>(XciInfo.UppHashSize).ToArray <byte>() : new byte[XciInfo.UppHashSize]; XciMeta xciMeta = new XciMeta(initialData); XciHeaderSource xciHeaderSource = new XciHeaderSource(ref xciInfo, xciMeta, rootPartitionFsHeaderHashSource, this.m_headerEncryptor, this.m_headerSigner); ReadableSubSink readableSubSink1 = new ReadableSubSink(outSink, 0L, memorySource.Size); this.ConnectionList.Add(new Connection((ISource)memorySource, (ISink)readableSubSink1)); ReadableSubSink readableSubSink2 = new ReadableSubSink(outSink, memorySource.Size, xciHeaderSource.Size); this.ConnectionList.Add(new Connection((ISource)xciHeaderSource, (ISink)readableSubSink2)); }