예제 #1
0
        public NintendoContentArchiveSource(NintendoContentFileSystemInfo fileSystemInfo, KeyConfiguration config, bool needsLogoPartition = false)
        {
            this.m_fileSystemInfo = fileSystemInfo;
            this.m_keyConfig      = config;
            this.SetCryptor(this.m_keyConfig);
            this.AddDefaultLogoPartitionIfNeeded(needsLogoPartition);
            fileSystemInfo.fsEntries.Sort((Comparison <NintendoContentFileSystemInfo.EntryInfo>)((x, y) => x.partitionIndex.CompareTo(y.partitionIndex)));
            NintendoContentFileSystemMeta meta = new NintendoContentFileSystemMeta();
            NintendoContentFileSystemEntryInfoContainer fsEntries = new NintendoContentFileSystemEntryInfoContainer(fileSystemInfo.fsEntries);
            List <ConcatenatedSource.Element>           elements1 = new List <ConcatenatedSource.Element>();

            NintendoContentArchiveSource.BodySourceElement[] bodySources = new NintendoContentArchiveSource.BodySourceElement[fileSystemInfo.fsEntries.Count];
            long offset = (long)meta.GetFsHeaderSize() * 4L;

            foreach (NintendoContentFileSystemInfo.EntryInfo entryInfo in fsEntries)
            {
                if (entryInfo.type != null)
                {
                    ISource source = NintendoContentArchiveSource.GetDataSource(entryInfo);
                    if (fileSystemInfo.isProdEncryption && fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 0)
                    {
                        source = this.AcidResignedSource(source);
                    }
                    if (fileSystemInfo.contentType == (byte)0 && entryInfo.partitionIndex == 1)
                    {
                        source = this.NrrSignedSource(source);
                    }
                    int currentIndex = fsEntries.CurrentIndex;
                    bodySources[currentIndex].DataOffset = offset;
                    NintendoContentArchiveSource.BuildDataInfo buildInfo = new NintendoContentArchiveSource.BuildDataInfo(meta, source, offset, currentIndex);
                    fileSystemInfo.fsEntries[currentIndex] = this.BuildData(entryInfo, buildInfo);
                    offset = buildInfo.CurrentOffset;
                    Sha256HierarchicalHashCalculatedSource calculatedSource = new Sha256HierarchicalHashCalculatedSource(buildInfo.HeaderSource, (int)buildInfo.HeaderSource.Size, 1);
                    ConcatenatedSource.Element             element1         = new ConcatenatedSource.Element(calculatedSource.GetMasterHashSource(), "fsHeaderHash" + (object)currentIndex, (long)(32 * currentIndex));
                    elements1.Add(element1);
                    ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource)calculatedSource, "fsHeader" + (object)currentIndex, (long)currentIndex * (long)meta.GetFsHeaderSize());
                    bodySources[currentIndex].HeaderElement      = element2;
                    bodySources[currentIndex].DataSourceElements = buildInfo.DataSourceElements;
                }
            }
            if (fsEntries.IsReverse)
            {
                elements1.Reverse();
            }
            NintendoContentArchiveSource.BodyEncryptionKey bodyEncryptionKey = new NintendoContentArchiveSource.BodyEncryptionKey(fileSystemInfo);
            this.MakeBody(meta, fsEntries, bodySources, bodyEncryptionKey);
            this.MakeNcaHeader(meta, (ISource) new ConcatenatedSource(elements1), bodyEncryptionKey);
            List <ConcatenatedSource.Element> elements2 = new List <ConcatenatedSource.Element>();

            ConcatenatedSource.Element element3 = new ConcatenatedSource.Element(this.m_headerSource, "header", 0L);
            ConcatenatedSource.Element element4 = new ConcatenatedSource.Element(this.m_bodySource, "body", element3.Source.Size);
            elements2.Add(element3);
            elements2.Add(element4);
            this.m_source = (ISource) new ConcatenatedSource(elements2);
            this.Size     = this.m_source.Size;
        }
        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 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)));
        }