private static NintendoContentFileSystemInfo.EntryInfo GetFsEntry(NintendoContentArchiveReader ncaReader, int fsIndex, EntryReplaceRule replaceRule) { NintendoContentArchiveFsHeaderInfo fsInfo = (NintendoContentArchiveFsHeaderInfo)null; IFileSystemArchiveReader systemArchiveReader = ncaReader.OpenFileSystemArchiveReader(fsIndex, ref fsInfo); NintendoContentFileSystemInfo.EntryInfo commonFsEntry = ArchiveReconstructionUtils.GetCommonFsEntry(fsInfo, fsIndex); Tuple <long, long> tuple = systemArchiveReader.GetFileFragmentList(replaceRule.Path).First <Tuple <long, long> >(); long offset = tuple.Item1; if (tuple.Item2 == replaceRule.Source.Size) { AdaptedSource adaptedSource = new AdaptedSource((ISource) new FileSystemArchvieBaseSource(systemArchiveReader), replaceRule.Source, offset, replaceRule.Source.Size); commonFsEntry.sourceInterface = (SourceInterface) new CliCompatibleSource((ISource)adaptedSource); } else if (commonFsEntry.formatType == "RomFs") { RomFsArchiveSource romFsArchiveSource = new RomFsArchiveSource(ArchiveReconstructionUtils.GetRomFsInfo(systemArchiveReader, replaceRule)); commonFsEntry.sourceInterface = (SourceInterface) new CliCompatibleSource((ISource)romFsArchiveSource); } else if (commonFsEntry.formatType == "PartitionFs") { PartitionFsArchiveSource partitionFsArchiveSource = new PartitionFsArchiveSource(ArchiveReconstructionUtils.GetPartitionFsInfo(systemArchiveReader, replaceRule)); commonFsEntry.sourceInterface = (SourceInterface) new CliCompatibleSource((ISource)partitionFsArchiveSource); } return(commonFsEntry); }
public ISource GetFsHeaderSource(NintendoContentFileSystemInfo.EntryInfo entryInfo) { NintendoContentFileSystemMeta contentFileSystemMeta = new NintendoContentFileSystemMeta(); byte[] ncaFsHeader = contentFileSystemMeta.CreateNcaFsHeader((ValueType)entryInfo, new byte[0]); int masterHashOffset = contentFileSystemMeta.GetHierarchicalSha256MasterHashOffset(); ISource masterHashSource = this.GetMasterHashSource(); return((ISource) new AdaptedSource((ISource) new MemorySource(ncaFsHeader, 0, ncaFsHeader.Length), masterHashSource, (long)masterHashOffset, masterHashSource.Size)); }
private static NintendoContentFileSystemInfo.EntryInfo GetFsEntry(NintendoContentArchiveReader ncaReader, int fsIndex) { NintendoContentArchiveFsHeaderInfo fsInfo = (NintendoContentArchiveFsHeaderInfo)null; IFileSystemArchiveReader reader = ncaReader.OpenFileSystemArchiveReader(fsIndex, ref fsInfo); NintendoContentFileSystemInfo.EntryInfo commonFsEntry = ArchiveReconstructionUtils.GetCommonFsEntry(fsInfo, fsIndex); FileSystemArchvieBaseSource archvieBaseSource = new FileSystemArchvieBaseSource(reader); commonFsEntry.sourceInterface = (SourceInterface) new CliCompatibleSource((ISource)archvieBaseSource); return(commonFsEntry); }
private void AddDefaultLogoPartitionIfNeeded(bool needsLogoPartition) { if (!this.NeedsDefaultLogoPartition(this.m_fileSystemInfo, needsLogoPartition)) { return; } NintendoContentFileSystemInfo.EntryInfo defaultLogoPartition = this.CreateDefaultLogoPartition(); defaultLogoPartition.partitionIndex = this.m_fileSystemInfo.fsEntries.Count <NintendoContentFileSystemInfo.EntryInfo>(); this.m_fileSystemInfo.fsEntries.Add(defaultLogoPartition); this.m_fileSystemInfo.numFsEntries = this.m_fileSystemInfo.fsEntries.Count <NintendoContentFileSystemInfo.EntryInfo>(); }
private NintendoContentFileSystemInfo.EntryInfo BuildData(NintendoContentFileSystemInfo.EntryInfo entryInfo, NintendoContentArchiveSource.BuildDataInfo buildInfo) { entryInfo.hashType = NintendoContentArchiveSource.VerifyHashType(this.m_fileSystemInfo, entryInfo); entryInfo.encryptionType = NintendoContentArchiveSource.VerifyEncryptionType(this.m_fileSystemInfo, entryInfo); entryInfo.startOffset = (ulong)buildInfo.CurrentOffset + buildInfo.Meta.GetHeaderSize(); entryInfo.hashTargetSize = (ulong)buildInfo.DataSource.Size; IHierarchicalHashCalculatedSource calculatedSource; switch (entryInfo.hashType) { case 2: calculatedSource = (IHierarchicalHashCalculatedSource) new Sha256HierarchicalHashCalculatedSource(buildInfo.DataSource, buildInfo.Meta.GetHashBlockSize((ValueType)entryInfo), 2); break; case 3: calculatedSource = (IHierarchicalHashCalculatedSource) new IntegrityHierarchicalHashCalculatedSource(buildInfo.DataSource); break; default: throw new NotImplementedException(); } long offset1 = 0; ISource layerHashSource = calculatedSource.GetLayerHashSource(); entryInfo.hashDataSize = (ulong)layerHashSource.Size; ConcatenatedSource.Element element1 = new ConcatenatedSource.Element(layerHashSource, "fsHash" + (object)buildInfo.Index, offset1); buildInfo.DataSourceElements.Add(element1); long offset2 = offset1 + element1.Source.Size; int num1 = (int)(offset2 % 512L); if (0 < num1) { ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource) new PaddingSource((long)(512 - num1)), "fsHashPadding" + (object)buildInfo.Index, offset2); buildInfo.DataSourceElements.Add(element2); offset2 += element2.Source.Size; } entryInfo.hashTargetOffset = (ulong)offset2; ConcatenatedSource.Element element3 = new ConcatenatedSource.Element((ISource)calculatedSource, "fsData" + (object)buildInfo.Index, offset2); buildInfo.DataSourceElements.Add(element3); long offset3 = offset2 + element3.Source.Size; int num2 = (int)(offset3 % 512L); if (0 < num2) { ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource) new PaddingSource((long)(512 - num2)), "fsDataPadding" + (object)buildInfo.Index, offset3); buildInfo.DataSourceElements.Add(element2); offset3 += element2.Source.Size; } buildInfo.CurrentOffset += offset3; entryInfo.endOffset = (ulong)buildInfo.CurrentOffset + buildInfo.Meta.GetHeaderSize(); buildInfo.HeaderSource = calculatedSource.GetFsHeaderSource(entryInfo); return(entryInfo); }
private static IFileSystemArchiveReader OpenFsReader(NintendoContentFileSystemInfo.EntryInfo entry, Stream stream) { string formatType = entry.formatType; if (formatType == "PartitionFs") { return((IFileSystemArchiveReader) new PartitionFileSystemArchiveReader(stream)); } if (formatType == "RomFs") { return((IFileSystemArchiveReader) new RomFsFileSystemArchiveReader(stream)); } throw new NotImplementedException(); }
public static ProgramInfoXml GetProgramInfoXml(List <NintendoSubmissionPackageFileSystemInfo.ContentInfo> contentInfos, KeyConfiguration config) { NintendoSubmissionPackageFileSystemInfo.ContentInfo contentInfo = contentInfos.Where <NintendoSubmissionPackageFileSystemInfo.ContentInfo>((Func <NintendoSubmissionPackageFileSystemInfo.ContentInfo, bool>)(x => x.ContentType == "Program")).ToList <NintendoSubmissionPackageFileSystemInfo.ContentInfo>().Single <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); string fileName = "main"; string filePath = ""; byte[] data = (byte[])null; bool flag = false; if (contentInfo.FsInfo != null) { NintendoContentFileSystemInfo.EntryInfo entryInfo = (contentInfo.FsInfo as NintendoContentFileSystemInfo).fsEntries.Where <NintendoContentFileSystemInfo.EntryInfo>((Func <NintendoContentFileSystemInfo.EntryInfo, bool>)(x => x.partitionIndex == 0)).Single <NintendoContentFileSystemInfo.EntryInfo>(); PartitionFileSystemInfo fileSystemInfo = (PartitionFileSystemInfo)entryInfo.fileSystemInfo; if (fileSystemInfo != null && fileSystemInfo.entries.Where <PartitionFileSystemInfo.EntryInfo>((Func <PartitionFileSystemInfo.EntryInfo, bool>)(x => x.name == fileName)).Count <PartitionFileSystemInfo.EntryInfo>() == 1) { flag = true; filePath = fileSystemInfo.entries.Where <PartitionFileSystemInfo.EntryInfo>((Func <PartitionFileSystemInfo.EntryInfo, bool>)(x => x.name == fileName)).Single <PartitionFileSystemInfo.EntryInfo>().path; using (SourceBasedStream sourceBasedStream = new SourceBasedStream(NintendoContentArchiveSource.GetDataSource(entryInfo))) { IFileSystemArchiveReader systemArchiveReader = NintendoSubmissionPackageArchiveUtils.OpenFsReader(entryInfo, (Stream)sourceBasedStream); data = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } } else { if (contentInfo.Source == null) { throw new NotImplementedException(); } byte[][] areaEncryptionKeys = config.GetKeyAreaEncryptionKeys(); using (SourceBasedStream sourceBasedStream = new SourceBasedStream(contentInfo.Source)) { IFileSystemArchiveReader systemArchiveReader = new NintendoContentArchiveReader((Stream)sourceBasedStream, areaEncryptionKeys).OpenFileSystemArchiveReader(0); if (systemArchiveReader.ListFileInfo().Where <Tuple <string, long> >((Func <Tuple <string, long>, bool>)(x => x.Item1 == fileName)).Count <Tuple <string, long> >() == 1) { flag = true; filePath = systemArchiveReader.ListFileInfo().Where <Tuple <string, long> >((Func <Tuple <string, long>, bool>)(x => x.Item1 == fileName)).Single <Tuple <string, long> >().Item1; data = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } } if (!flag) { Log.Warning("\"main\" was not found in code region."); data = new byte[0]; } return(new ProgramInfoXml(new SymbolExtract(data, filePath))); }
private NintendoContentFileSystemInfo.EntryInfo CreateDefaultLogoPartition() { NintendoContentFileSystemInfo.EntryInfo entryInfo1 = new NintendoContentFileSystemInfo.EntryInfo(); entryInfo1.type = "format"; entryInfo1.partitionType = "logo"; entryInfo1.formatType = "PartitionFs"; entryInfo1.version = (ushort)2; entryInfo1.hashType = (byte)2; entryInfo1.encryptionType = (byte)1; PartitionFileSystemInfo partitionFileSystemInfo = new PartitionFileSystemInfo(); var dataArray = new[] { new { Data = Logo.NintendoLogo, FileName = "NintendoLogo.png" }, new { Data = Logo.StartupMovie, FileName = "StartupMovie.gif" } }; ulong num = 0; foreach (var data1 in dataArray) { byte[] data2 = data1.Data; string fileName = data1.FileName; PartitionFileSystemInfo.EntryInfo entryInfo2 = new PartitionFileSystemInfo.EntryInfo(); entryInfo2.type = "file"; entryInfo2.name = fileName; entryInfo2.offset = num; entryInfo2.size = (ulong)data2.Length; entryInfo2.sourceInterface = (SourceInterface) new CliCompatibleSource((ISource) new MemorySource(data2, 0, data2.Length)); partitionFileSystemInfo.entries.Add(entryInfo2); num += entryInfo2.size; } entryInfo1.fileSystemInfo = (Nintendo.Authoring.FileSystemMetaLibrary.FileSystemInfo)partitionFileSystemInfo; return(entryInfo1); }
internal static ISource GetDataSource(NintendoContentFileSystemInfo.EntryInfo fsEntry) { if (fsEntry.type == "format") { string formatType = fsEntry.formatType; if (formatType == "PartitionFs") { return((ISource) new PartitionFsArchiveSource(fsEntry.fileSystemInfo as PartitionFileSystemInfo)); } if (formatType == "RomFs") { return((ISource) new RomFsArchiveSource(fsEntry.fileSystemInfo as RomFsFileSystemInfo)); } throw new NotImplementedException(); } if (fsEntry.type == "source") { return((ISource)fsEntry.sourceInterface); } throw new NotImplementedException(); }
public static ApplicationControlPropertyModel GetApplicationControlProperty(List <NintendoSubmissionPackageFileSystemInfo.ContentInfo> contentInfos, KeyConfiguration config) { List <NintendoSubmissionPackageFileSystemInfo.ContentInfo> list = contentInfos.Where <NintendoSubmissionPackageFileSystemInfo.ContentInfo>((Func <NintendoSubmissionPackageFileSystemInfo.ContentInfo, bool>)(x => x.ContentType == "Control")).ToList <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); if (list.Count > 1) { throw new NotImplementedException("Multiple control contents in an Application are not supported."); } NintendoSubmissionPackageFileSystemInfo.ContentInfo contentInfo = list.Single <NintendoSubmissionPackageFileSystemInfo.ContentInfo>(); string fileName = "control.nacp"; byte[] bytes; if (contentInfo.FsInfo != null) { NintendoContentFileSystemInfo.EntryInfo entryInfo = (contentInfo.FsInfo as NintendoContentFileSystemInfo).fsEntries.Single <NintendoContentFileSystemInfo.EntryInfo>(); using (SourceBasedStream sourceBasedStream = new SourceBasedStream(NintendoContentArchiveSource.GetDataSource(entryInfo))) { IFileSystemArchiveReader systemArchiveReader = NintendoSubmissionPackageArchiveUtils.OpenFsReader(entryInfo, (Stream)sourceBasedStream); bytes = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } else { if (contentInfo.Source == null) { throw new NotImplementedException(); } byte[][] areaEncryptionKeys = config.GetKeyAreaEncryptionKeys(); using (SourceBasedStream sourceBasedStream = new SourceBasedStream(contentInfo.Source)) { IFileSystemArchiveReader systemArchiveReader = new NintendoContentArchiveReader((Stream)sourceBasedStream, areaEncryptionKeys).OpenFileSystemArchiveReader(0); bytes = systemArchiveReader.ReadFile(fileName, 0L, systemArchiveReader.GetFileSize(fileName)); } } return(ApplicationControlPropertyModel.PropertyBytesToModel(bytes)); }
public NintendoContentFileSystemInfo GetFileSystemInfo() { NintendoContentFileSystemInfo fileSystemInfo1 = new NintendoContentFileSystemInfo(); using (StreamReader streamReader = new StreamReader(this.m_adfPath, Encoding.UTF8)) { YamlStream yamlStream = new YamlStream(); yamlStream.Load((TextReader)streamReader); YamlMappingNode rootNode; YamlSequenceNode child1; try { rootNode = (YamlMappingNode)yamlStream.Documents[0].RootNode; if (((YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("formatType")]).Value != "NintendoContent") { throw new ArgumentException(); } YamlScalarNode child2 = (YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("contentType")]; YamlScalarNode child3 = (YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("keyGeneration")]; YamlScalarNode child4 = (YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("programId")]; YamlScalarNode child5 = (YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("contentIndex")]; child1 = (YamlSequenceNode)rootNode.Children[(YamlNode) new YamlScalarNode("entries")]; fileSystemInfo1.contentType = this.ConvertToContentTypeByte(child2.Value); fileSystemInfo1.keyGeneration = Convert.ToByte(child3.Value); fileSystemInfo1.programId = Convert.ToUInt64(child4.Value, 16); fileSystemInfo1.contentIndex = Convert.ToUInt32(child5.Value); } catch { throw new ArgumentException("invalid format .adf file."); } try { YamlScalarNode child2 = (YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("keyAreaEncryptionKeyIndex")]; fileSystemInfo1.keyAreaEncryptionKeyIndex = Convert.ToByte(child2.Value); } catch { fileSystemInfo1.keyAreaEncryptionKeyIndex = (byte)0; } string descFilePath; if (fileSystemInfo1.contentType == (byte)0) { try { descFilePath = ((YamlScalarNode)rootNode.Children[(YamlNode) new YamlScalarNode("descFilePath")]).Value; } catch { throw new ArgumentException(".desc file is not specified for program content."); } } else { descFilePath = (string)null; } byte[] numArray = (byte[])null; if (descFilePath != null) { numArray = NintendoContentAdfReader.RetrieveInfoFromDesc(ref fileSystemInfo1, descFilePath); } foreach (YamlMappingNode yamlMappingNode in child1) { NintendoContentFileSystemInfo.EntryInfo entryInfo1 = new NintendoContentFileSystemInfo.EntryInfo(); string adfPath = (string)null; foreach (KeyValuePair <YamlNode, YamlNode> keyValuePair in yamlMappingNode) { switch (((YamlScalarNode)keyValuePair.Key).Value) { case "encryptionType": entryInfo1.encryptionType = Convert.ToByte(((YamlScalarNode)keyValuePair.Value).Value); continue; case "formatType": entryInfo1.formatType = ((YamlScalarNode)keyValuePair.Value).Value; continue; case "hashType": entryInfo1.hashType = Convert.ToByte(((YamlScalarNode)keyValuePair.Value).Value); continue; case "partitionType": entryInfo1.partitionType = ((YamlScalarNode)keyValuePair.Value).Value; entryInfo1.partitionIndex = this.GetPartitionIndex(entryInfo1.partitionType); continue; case "path": adfPath = ((YamlScalarNode)keyValuePair.Value).Value; continue; case "type": entryInfo1.type = ((YamlScalarNode)keyValuePair.Value).Value; continue; case "version": entryInfo1.version = Convert.ToUInt16(((YamlScalarNode)keyValuePair.Value).Value); continue; default: throw new ArgumentException("invalid format .adf file. invalid key is specified\n" + yamlMappingNode.ToString()); } } if (entryInfo1.type == null || entryInfo1.formatType == null || adfPath == null) { throw new ArgumentException("invalid format .adf file. \"type\" or \"formatType\" is not specified\n" + yamlMappingNode.ToString()); } entryInfo1.version = (ushort)2; entryInfo1.hashType = NintendoContentArchiveSource.VerifyHashType(fileSystemInfo1, entryInfo1); entryInfo1.encryptionType = NintendoContentArchiveSource.VerifyEncryptionType(fileSystemInfo1, entryInfo1); string formatType = entryInfo1.formatType; if (!(formatType == "PartitionFs")) { if (!(formatType == "RomFs")) { throw new NotImplementedException("invalid format .adf file. invalid formatType." + yamlMappingNode.ToString()); } RomFsAdfReader romFsAdfReader = new RomFsAdfReader(adfPath); entryInfo1.fileSystemInfo = (Nintendo.Authoring.FileSystemMetaLibrary.FileSystemInfo)romFsAdfReader.GetFileSystemInfo(); } else { PartitionFileSystemInfo fileSystemInfo2 = new PartitionFsAdfReader(adfPath).GetFileSystemInfo(); if (numArray != null && entryInfo1.partitionType == "code") { IEnumerable <PartitionFileSystemInfo.EntryInfo> source = fileSystemInfo2.entries.Where <PartitionFileSystemInfo.EntryInfo>((Func <PartitionFileSystemInfo.EntryInfo, bool>)(p => p.name == "main.npdm")); if (fileSystemInfo1.contentType == (byte)0 && source.Count <PartitionFileSystemInfo.EntryInfo>() != 1) { throw new ArgumentException("\"main.npdm\" must be included in the code region."); } foreach (PartitionFileSystemInfo.EntryInfo entryInfo2 in source) { if (!((IEnumerable <byte>) this.ReadAcid(entryInfo2.path)).SequenceEqual <byte>((IEnumerable <byte>)numArray)) { throw new ArgumentException(".desc file specified differ from the one used to build code."); } } } entryInfo1.fileSystemInfo = (Nintendo.Authoring.FileSystemMetaLibrary.FileSystemInfo)fileSystemInfo2; } fileSystemInfo1.fsEntries.Add(entryInfo1); } } fileSystemInfo1.numFsEntries = fileSystemInfo1.fsEntries.Count; fileSystemInfo1.isProdEncryption = false; return(fileSystemInfo1); }
public static byte VerifyEncryptionType(NintendoContentFileSystemInfo fileSystemInfo, NintendoContentFileSystemInfo.EntryInfo entryInfo) { NintendoContentArchiveEncryptionType archiveEncryptionType = (NintendoContentArchiveEncryptionType)entryInfo.encryptionType; if (archiveEncryptionType == NintendoContentArchiveEncryptionType.Auto) { if (fileSystemInfo.contentType == (byte)0) { switch (entryInfo.partitionIndex) { case 0: case 1: archiveEncryptionType = NintendoContentArchiveEncryptionType.AesCtr; break; case 2: archiveEncryptionType = NintendoContentArchiveEncryptionType.None; break; default: throw new InvalidDataException("invalid partition index."); } } else { archiveEncryptionType = NintendoContentArchiveEncryptionType.AesCtr; } } if (fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 2 && archiveEncryptionType != NintendoContentArchiveEncryptionType.None) { throw new InvalidDataException("logo must be no encryption type."); } if (archiveEncryptionType != NintendoContentArchiveEncryptionType.None && archiveEncryptionType != NintendoContentArchiveEncryptionType.AesCtr) { throw new InvalidDataException("invalid encryption type."); } return((byte)archiveEncryptionType); }
public static byte VerifyHashType(NintendoContentFileSystemInfo fileSystemInfo, NintendoContentFileSystemInfo.EntryInfo entryInfo) { NintendoContentArchiveHashType contentArchiveHashType = (NintendoContentArchiveHashType)entryInfo.hashType; if (contentArchiveHashType == NintendoContentArchiveHashType.Auto) { string formatType = entryInfo.formatType; if (!(formatType == "PartitionFs")) { if (!(formatType == "RomFs")) { throw new InvalidDataException("invalid format type."); } contentArchiveHashType = NintendoContentArchiveHashType.HierarchicalIntegrity; } else { contentArchiveHashType = NintendoContentArchiveHashType.HierarchicalSha256; } } if (contentArchiveHashType != NintendoContentArchiveHashType.HierarchicalSha256 && contentArchiveHashType != NintendoContentArchiveHashType.HierarchicalIntegrity) { throw new InvalidDataException("invalid hash type."); } return((byte)contentArchiveHashType); }