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);
        }
        internal static NintendoContentFileSystemInfo GetReplacedNcaInfo(NintendoContentArchiveReader ncaReader, string descFilePath, EntryReplaceRule replaceRule)
        {
            NintendoContentFileSystemInfo commonNcaInfo = ArchiveReconstructionUtils.GetCommonNcaInfo(ncaReader);

            commonNcaInfo.keyAreaEncryptionKeyIndex = ncaReader.GetKeyIndex();
            commonNcaInfo.isProdEncryption          = false;
            if (descFilePath != null)
            {
                NintendoContentAdfReader.RetrieveInfoFromDesc(ref commonNcaInfo, descFilePath);
            }
            else if (replaceRule != null && commonNcaInfo.contentType == (byte)0)
            {
                throw new Exception("Replacing 'Program' content needs desc file.");
            }
            for (int fsIndex = 0; fsIndex < commonNcaInfo.numFsEntries; ++fsIndex)
            {
                string str = string.Format("fs{0}", (object)fsIndex);
                if (replaceRule != null && replaceRule.Path.StartsWith(str))
                {
                    EntryReplaceRule replaceRule1 = replaceRule;
                    replaceRule1.Path = replaceRule1.Path.Substring(str.Length + 1);
                    commonNcaInfo.fsEntries.Add(ArchiveReconstructionUtils.GetFsEntry(ncaReader, fsIndex, replaceRule1));
                }
                else
                {
                    commonNcaInfo.fsEntries.Add(ArchiveReconstructionUtils.GetFsEntry(ncaReader, fsIndex));
                }
            }
            return(commonNcaInfo);
        }
Пример #3
0
        private static void ExtractNca(NintendoContentArchiveReader reader, string outputDirectoryPath, string targetEntryPath)
        {
            bool flag1 = false;
            bool flag2 = !string.IsNullOrEmpty(targetEntryPath);

            Directory.CreateDirectory(outputDirectoryPath);
            foreach (Tuple <int, long> tuple1 in reader.ListFsInfo())
            {
                int index = tuple1.Item1;
                IFileSystemArchiveReader fsReader = reader.OpenFileSystemArchiveReader(index);
                foreach (Tuple <string, long> tuple2 in fsReader.ListFileInfo())
                {
                    string str1     = tuple2.Item1;
                    long   fileSize = tuple2.Item2;
                    string str2     = string.Format("fs{0}/{1}", (object)index, (object)str1);
                    if (!Program.FsUtil.CheckShouldSkipComparePath(targetEntryPath, str2))
                    {
                        string str3 = Path.Combine(outputDirectoryPath, Path.GetFileName(str1));
                        if (!flag2)
                        {
                            str3 = Path.Combine(outputDirectoryPath, str2);
                            Directory.CreateDirectory(Path.GetDirectoryName(str3));
                        }
                        Console.WriteLine("  Extracting {0}\t({1} byte)", (object)str2, (object)fileSize);
                        Program.FsUtil.WriteFile(fsReader, str3, str1, fileSize);
                        flag1 = true;
                    }
                }
            }
            if (!flag1)
            {
                throw new ExtractEntryNotFoundException();
            }
        }
        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);
        }
        internal static NintendoContentFileSystemInfo GetProdNcaInfo(NintendoContentArchiveReader ncaReader)
        {
            NintendoContentFileSystemInfo commonNcaInfo = ArchiveReconstructionUtils.GetCommonNcaInfo(ncaReader);

            commonNcaInfo.keyAreaEncryptionKeyIndex = (byte)0;
            commonNcaInfo.isProdEncryption          = true;
            for (int fsIndex = 0; fsIndex < commonNcaInfo.numFsEntries; ++fsIndex)
            {
                commonNcaInfo.fsEntries.Add(ArchiveReconstructionUtils.GetFsEntry(ncaReader, fsIndex));
            }
            return(commonNcaInfo);
        }
Пример #6
0
        public ModifiableNintendoContentArchive(IReadableSink outSink, NintendoContentArchiveReader ncaReader, ISource inSource, string targetEntryPath, string descFilePath, KeyConfiguration keyConfig)
        {
            this.m_KeyConfig = keyConfig;
            NintendoContentArchiveSource contentArchiveSource = new NintendoContentArchiveSource(ArchiveReconstructionUtils.GetReplacedNcaInfo(ncaReader, descFilePath, new EntryReplaceRule()
            {
                Source = inSource,
                Path   = targetEntryPath
            }), this.m_KeyConfig, false);

            outSink.SetSize(contentArchiveSource.Size);
            this.ConnectionList = new List <Connection>();
            this.ConnectionList.Add(new Connection((ISource)contentArchiveSource, (ISink)outSink));
        }
        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 static NintendoContentFileSystemInfo GetCommonNcaInfo(NintendoContentArchiveReader ncaReader)
 {
     return(new NintendoContentFileSystemInfo()
     {
         distributionType = ncaReader.GetDistributionType(),
         contentType = ncaReader.GetContentType(),
         keyGeneration = ncaReader.GetKeyGeneration(),
         programId = ncaReader.GetProgramId(),
         contentIndex = ncaReader.GetContentIndex(),
         numFsEntries = ncaReader.GetFsCount(),
         sdkAddonVersion = ncaReader.GetSdkAddonVersion(),
         keyAreaEncryptionKeyIndex = 0,
         isProdEncryption = false
     });
 }
Пример #9
0
        private static void ListNca(NintendoContentArchiveReader reader, string ncaName)
        {
            int val1 = 10;

            ncaName = string.IsNullOrEmpty(ncaName) ? "" : ncaName + "/";
            foreach (Tuple <int, long> tuple1 in reader.ListFsInfo())
            {
                int index = tuple1.Item1;
                foreach (Tuple <string, long> tuple2 in reader.OpenFileSystemArchiveReader(index).ListFileInfo())
                {
                    string str1 = tuple2.Item1;
                    long   num  = tuple2.Item2;
                    string str2 = string.Format("{0}fs{1}/{2}", (object)ncaName, (object)index, (object)str1);
                    val1 = Math.Max(val1, str2.Length);
                    Console.WriteLine("{0}\t({1} byte)", (object)str2.PadRight(val1 + 1), (object)num);
                }
            }
        }
        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));
        }
        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.");
        }
Пример #12
0
        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.");
            }
        }