예제 #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;
        }
예제 #2
0
        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);
        }