Example #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;
        }
Example #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);
        }
        internal NintendoContentMetaArchiveSource(NintendoContentMetaBase contentMeta, int keyEncryptionKeyIndex, KeyConfiguration config, bool isProdEncryption, bool isGameCard)
        {
            NintendoContentMetaReader contentMetaReader = new NintendoContentMetaReader(contentMeta.GetBytes());
            ISource source1 = contentMeta.GetSource();
            PartitionFileSystemInfo partitionFileSystemInfo = new PartitionFileSystemInfo();

            partitionFileSystemInfo.version = 0;
            partitionFileSystemInfo.entries.Add(new PartitionFileSystemInfo.EntryInfo()
            {
                type   = "source",
                name   = contentMeta.GetEntryName(),
                offset = 0UL,
                size   = (ulong)source1.Size
            });
            PartitionFileSystemMeta           partitionFileSystemMeta = new PartitionFileSystemMeta();
            List <ConcatenatedSource.Element> elements       = new List <ConcatenatedSource.Element>();
            PartitionFileSystemInfo           fileSystemInfo = partitionFileSystemInfo;

            byte[] buffer = partitionFileSystemMeta.Create(fileSystemInfo);
            ConcatenatedSource.Element element1 = new ConcatenatedSource.Element((ISource) new MemorySource(buffer, 0, buffer.Length), "meta", 0L);
            ConcatenatedSource.Element element2 = new ConcatenatedSource.Element(source1, "body", element1.Source.Size);
            elements.Add(element1);
            elements.Add(element2);
            ISource source2 = (ISource) new ConcatenatedSource(elements);

            this.m_source = (ISource) new NintendoContentArchiveSource(new NintendoContentFileSystemInfo()
            {
                distributionType          = isGameCard ? (byte)1 : (byte)0,
                contentType               = (byte)1,
                keyGeneration             = (byte)0,
                programId                 = contentMetaReader.GetId(),
                contentIndex              = 0U,
                keyAreaEncryptionKeyIndex = (byte)keyEncryptionKeyIndex,
                isProdEncryption          = isProdEncryption,
                fsEntries                 =
                {
                    new NintendoContentFileSystemInfo.EntryInfo()
                    {
                        type            = "source",
                        formatType      = "PartitionFs",
                        sourceInterface = (SourceInterface) new CliCompatibleSource(source2),
                        version         = (ushort)2,
                        hashType        = (byte)0,
                        encryptionType  = (byte)0
                    }
                },
                numFsEntries = 1
            }, config, false);
            this.Size = this.m_source.Size;
        }
        public ISource GetLayerHashSource()
        {
            if (this.m_hashLayerCount == 1)
            {
                return(this.GetMasterHashSource());
            }
            List <ConcatenatedSource.Element> elements = new List <ConcatenatedSource.Element>();
            long offset = 0;

            for (int index = 1; index < this.m_hashLayerCount; ++index)
            {
                ConcatenatedSource.Element element = new ConcatenatedSource.Element((ISource) new SinkLinkedSource((ISink)this.m_hierarchicalHashValueSinkList[index], this.m_hierarchicalHashValueSinkList[index].ToSource()), "Hash:L" + (object)index, offset);
                offset += this.m_hierarchicalHashValueSinkList[index].Size;
                elements.Add(element);
            }
            return((ISource) new ConcatenatedSource(elements));
        }
Example #5
0
        private void MakeBody(NintendoContentFileSystemMeta meta, NintendoContentFileSystemEntryInfoContainer fsEntries, NintendoContentArchiveSource.BodySourceElement[] bodySources, NintendoContentArchiveSource.BodyEncryptionKey bodyEncryptionKey)
        {
            List <ConcatenatedSource.Element> elements = new List <ConcatenatedSource.Element>();

            for (int index = 0; index < bodySources.Length; ++index)
            {
                if (bodySources[index].HeaderElement == null)
                {
                    PaddingSource paddingSource = new PaddingSource((long)meta.GetFsHeaderSize());
                    elements.Add(new ConcatenatedSource.Element((ISource)paddingSource, "fsHeader" + (object)index, (long)index * (long)meta.GetFsHeaderSize()));
                }
                else
                {
                    ConcatenatedSource.Element headerElement = bodySources[index].HeaderElement;
                    ISource source = (ISource) new Aes128XtsEncryptedSource(headerElement.Source, this.m_headerEncryptor);
                    elements.Add(new ConcatenatedSource.Element(source, headerElement.Signature, headerElement.Offset));
                }
            }
            for (int length = bodySources.Length; length < 4; ++length)
            {
                PaddingSource paddingSource = new PaddingSource((long)meta.GetFsHeaderSize());
                elements.Add(new ConcatenatedSource.Element((ISource)paddingSource, "fsHeader" + (object)length, (long)length * (long)meta.GetFsHeaderSize()));
            }
            foreach (NintendoContentFileSystemInfo.EntryInfo fsEntry in fsEntries)
            {
                int     currentIndex = fsEntries.CurrentIndex;
                ISource source       = (ISource) new ConcatenatedSource(bodySources[currentIndex].DataSourceElements);
                switch (fsEntry.encryptionType)
                {
                case 1:
                    elements.Add(new ConcatenatedSource.Element(source, "fsData" + (object)currentIndex, bodySources[currentIndex].DataOffset));
                    continue;

                case 3:
                    source = (ISource) new Aes128CtrEncryptedSource(source, (ICtrModeEncryptor) new Aes128CtrCryptoDriver(bodyEncryptionKey.GetInternalKey(NintendoContentArchiveEncryptionKeyIndex.AesCtr)), (int)this.m_fileSystemInfo.keyGeneration, (long)fsEntry.startOffset);
                    goto case 1;

                default:
                    throw new InvalidDataException();
                }
            }
            this.m_bodySource = (ISource) new ConcatenatedSource(elements);
            this.m_fileSystemInfo.contentSize = meta.GetHeaderSize() + (ulong)this.m_bodySource.Size;
        }
        public PartitionFsArchiveSource(PartitionFileSystemInfo fileSystemInfo)
        {
            PartitionFileSystemMeta           partitionFileSystemMeta = new PartitionFileSystemMeta();
            List <ConcatenatedSource.Element> elements        = new List <ConcatenatedSource.Element>();
            PartitionFileSystemInfo           fileSystemInfo1 = fileSystemInfo;

            byte[] buffer = partitionFileSystemMeta.Create(fileSystemInfo1);
            ConcatenatedSource.Element element1 = new ConcatenatedSource.Element((ISource) new MemorySource(buffer, 0, buffer.Length), "meta", 0L);
            elements.Add(element1);
            long size = element1.Source.Size;

            foreach (PartitionFileSystemInfo.EntryInfo entry in fileSystemInfo.entries)
            {
                ConcatenatedSource.Element element2 = new ConcatenatedSource.Element(entry.sourceInterface != null ? (ISource)entry.sourceInterface : (ISource) new FileSource(entry.path, 0L, (long)entry.size), entry.name, (long)entry.offset + size);
                elements.Add(element2);
            }
            this.m_source = (ISource) new ConcatenatedSource(elements);
            this.Size     = this.m_source.Size;
        }
        public ByteData PullData(long offset, int size)
        {
            int count1 = 0;

            byte[] array1  = new byte[size];
            long   offset1 = offset;

            while (count1 != size)
            {
                ConcatenatedSource.Element element = this.GetElement(offset1);
                ByteData            byteData       = element.Source.PullData(offset1 - element.Offset, size - count1);
                ArraySegment <byte> buffer         = byteData.Buffer;
                if (buffer.Count != 0)
                {
                    buffer = byteData.Buffer;
                    byte[] array2 = buffer.Array;
                    buffer = byteData.Buffer;
                    int    offset2   = buffer.Offset;
                    byte[] numArray  = array1;
                    int    dstOffset = count1;
                    buffer = byteData.Buffer;
                    int count2 = buffer.Count;
                    Buffer.BlockCopy((Array)array2, offset2, (Array)numArray, dstOffset, count2);
                    int num1 = count1;
                    buffer = byteData.Buffer;
                    int count3 = buffer.Count;
                    count1 = num1 + count3;
                    long num2 = offset1;
                    buffer = byteData.Buffer;
                    long count4 = (long)buffer.Count;
                    offset1 = num2 + count4;
                }
                else
                {
                    break;
                }
            }
            return(new ByteData(new ArraySegment <byte>(array1, 0, count1)));
        }
 public ConcatenatedSource(List <ConcatenatedSource.Element> elements)
 {
     this.Elements = new List <ConcatenatedSource.Element>();
     foreach (ConcatenatedSource.Element element in elements)
     {
         this.Elements.Add(element);
     }
     this.Elements.Sort((IComparer <ConcatenatedSource.Element>) new ConcatenatedSource.ElementOffsetComparer());
     for (int index = 0; index < this.Elements.Count - 1; ++index)
     {
         long size = this.Elements[index + 1].Offset - (this.Elements[index].Offset + this.Elements[index].Source.Size);
         if (size < 0L)
         {
             throw new ArgumentException("entries layout overlaps. please check .adf file.");
         }
         if (size > 0L)
         {
             ConcatenatedSource.Element element = new ConcatenatedSource.Element((ISource) new PaddingSource(size), string.Empty, this.Elements[index].Offset + this.Elements[index].Source.Size);
             this.Elements.Insert(index + 1, element);
         }
     }
     this.Size = this.Elements.Last <ConcatenatedSource.Element>().Offset + this.Elements.Last <ConcatenatedSource.Element>().Source.Size;
 }
Example #9
0
        public RomFsArchiveSource(RomFsFileSystemInfo fileSystemInfo)
        {
            RomFsFileSystemMeta fsFileSystemMeta       = new RomFsFileSystemMeta();
            List <ConcatenatedSource.Element> elements = new List <ConcatenatedSource.Element>();
            RomFsFileSystemInfo     fileSystemInfo1    = fileSystemInfo;
            RomFsFileSystemMetaInfo fileSystemMetaInfo = fsFileSystemMeta.Create(fileSystemInfo1);

            ConcatenatedSource.Element element1 = new ConcatenatedSource.Element((ISource) new MemorySource(fileSystemMetaInfo.header, 0, fileSystemMetaInfo.header.Length), "meta_header", 0L);
            elements.Add(element1);
            long size = element1.Source.Size;

            foreach (RomFsFileSystemInfo.EntryInfo entry in fileSystemInfo.entries)
            {
                if (entry.type == "file")
                {
                    ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource) new FileSource(entry.path, 0L, (long)entry.size), entry.name, (long)entry.offset + size);
                    elements.Add(element2);
                }
                else if (entry.type == "source")
                {
                    ConcatenatedSource.Element element2 = new ConcatenatedSource.Element((ISource)entry.sourceInterface, entry.name, (long)entry.offset + size);
                    elements.Add(element2);
                }
            }
            RomFsFileSystemInfo.EntryInfo entry1 = fileSystemInfo.entries[fileSystemInfo.entries.Count - 1];
            long offset = size + (long)entry1.offset + (long)entry1.size;

            if (fileSystemMetaInfo.offsetData > offset)
            {
                elements.Add(new ConcatenatedSource.Element((ISource) new PaddingSource(fileSystemMetaInfo.offsetData - offset), "romFsMetaBodyPadding", offset));
            }
            ConcatenatedSource.Element element3 = new ConcatenatedSource.Element((ISource) new MemorySource(fileSystemMetaInfo.data, 0, fileSystemMetaInfo.data.Length), "meta_data", fileSystemMetaInfo.offsetData);
            elements.Add(element3);
            this.m_source = (ISource) new ConcatenatedSource(elements);
            this.Size     = this.m_source.Size;
        }