示例#1
0
        public static void Decrypt(PartitionFileSystem pfs, string outDirPath, bool verifyBeforeDecrypting, Keyset keyset, Output Out)
        {
            Out.Log(pfs.Print());
            ProcessNsp.GetTitlekey(pfs, keyset, Out);
            var         OutDirFs   = new LocalFileSystem(outDirPath);
            IDirectory  sourceRoot = pfs.OpenDirectory("/", OpenDirectoryMode.All);
            IDirectory  destRoot   = OutDirFs.OpenDirectory("/", OpenDirectoryMode.All);
            IFileSystem sourceFs   = sourceRoot.ParentFileSystem;
            IFileSystem destFs     = destRoot.ParentFileSystem;

            foreach (var entry in FileIterator(sourceRoot))
            {
                destFs.CreateFile(entry.Name, entry.Size, CreateFileOptions.None);
                using (IFile srcFile = sourceFs.OpenFile(entry.Name, OpenMode.Read))
                    using (IFile dstFile = destFs.OpenFile(entry.Name, OpenMode.Write))
                    {
                        if (entry.Name.EndsWith(".nca"))
                        {
                            ProcessNca.Process(srcFile, dstFile, verifyBeforeDecrypting, keyset, Out);
                        }
                        else
                        {
                            srcFile.CopyTo(dstFile);
                        }
                    }
            }
        }
示例#2
0
        public static void ExtractRomFS(string inFile, string outDirPath, Keyset keyset, Output Out)
        {
            using (var file = new FileStream(inFile, FileMode.Open, FileAccess.Read))
            {
                var         pfs        = new PartitionFileSystem(file.AsStorage());
                var         OutDirFs   = new LocalFileSystem(outDirPath);
                IDirectory  sourceRoot = pfs.OpenDirectory("/", OpenDirectoryMode.All);
                IFileSystem sourceFs   = sourceRoot.ParentFileSystem;
                Out.Log(pfs.Print());

                foreach (var entry in FileIterator(sourceRoot))
                {
                    if (entry.Name.EndsWith(".nca"))
                    {
                        var fullOutDirPath = $"{outDirPath}/{entry.Name}";
                        Out.Log($"Extracting {entry.Name}...\r\n");
                        using (IFile srcFile = sourceFs.OpenFile(entry.Name, OpenMode.Read))
                        {
                            ProcessNca.Extract(srcFile.AsStream(), fullOutDirPath, true, keyset, Out);
                        }
                    }
                    else if (entry.Name.EndsWith(".nca.nsz"))
                    {
                        var fullOutDirPath = $"{outDirPath}/{entry.Name}";
                        Out.Log($"Extracting {entry.Name}...\r\n");
                        using (IFile srcFile = sourceFs.OpenFile(entry.Name, OpenMode.Read))
                            using (var decompressedFile = new DecompressionStorage(srcFile))
                            {
                                ProcessNca.Extract(decompressedFile.AsStream(), fullOutDirPath, true, keyset, Out, true);

                                // Header can't be patched for now due to OpenSection
                                // and ValidateMasterHash needs to know if AesCtrEx
                                // so Nca.cs was patched and now accepts isDecryptedNca
                                // as constructor argument which disables decryption

                                /*
                                 * var DecryptedHeader = new byte[0xC00];
                                 * decompressedFile.AsStream().Read(DecryptedHeader, 0, 0xC00);
                                 * DecryptedHeader[1028] = (int)NcaEncryptionType.None;
                                 * DecryptedHeader[1540] = (int)NcaEncryptionType.None;
                                 * DecryptedHeader[2052] = (int)NcaEncryptionType.None;
                                 * DecryptedHeader[2564] = (int)NcaEncryptionType.None;
                                 * var HeaderKey1 = new byte[16];
                                 * var HeaderKey2 = new byte[16];
                                 * Buffer.BlockCopy(keyset.HeaderKey, 0, HeaderKey1, 0, 16);
                                 * Buffer.BlockCopy(keyset.HeaderKey, 16, HeaderKey2, 0, 16);
                                 * var headerEncrypted = CryptoInitialisers.AES_XTS(HeaderKey1, HeaderKey2, 0x200, DecryptedHeader, 0);
                                 * var ncaStorageList = new List<IStorage>() { new MemoryStorage(headerEncrypted), decompressedFile.Slice(0xC00) };
                                 * var cleanDecryptedNca = new ConcatenationStorage(ncaStorageList, true);
                                 * ProcessNca.Extract(cleanDecryptedNca.AsStream(), fullOutDirPath, true, keyset, Out);
                                 */
                            }
                    }
                }
            }
        }
示例#3
0
        private static void Process(string inputFilePath, string outDirPath, XciTaskType taskType, Keyset keyset, Output Out, bool verifyBeforeDecrypting = true)
        {
            using (var inputFile = File.Open(inputFilePath, FileMode.Open, FileAccess.Read).AsStorage())
                using (var outputFile = File.Open($"{outDirPath}/xciMeta.dat", FileMode.Create))
                {
                    var         OutDirFs = new LocalFileSystem(outDirPath);
                    IDirectory  destRoot = OutDirFs.OpenDirectory("/", OpenDirectoryMode.All);
                    IFileSystem destFs   = destRoot.ParentFileSystem;

                    var header = new byte[] { 0x6e, 0x73, 0x5a, 0x69, 0x70, 0x4d, 0x65, 0x74, 0x61, 0x58, 0x43, 0x49, 0x00 };
                    outputFile.Write(header, 0, header.Length);

                    var xci           = new Xci(keyset, inputFile);
                    var xciHeaderData = new byte[0x200];
                    var xciCertData   = new byte[0x200];
                    inputFile.Read(xciHeaderData, 0);
                    inputFile.Read(xciCertData, 0x7000);
                    outputFile.Write(xciHeaderData, 0, 0x200);
                    outputFile.Write(xciCertData, 0, 0x200);

                    Out.Log(Print.PrintXci(xci));

                    var root = xci.OpenPartition(XciPartitionType.Root);
                    if (root == null)
                    {
                        throw new InvalidDataException("Could not find root partition");
                    }

                    ProcessXci.GetTitleKeys(xci, keyset, Out);
                    foreach (var sub in root.Files)
                    {
                        outputFile.WriteByte(0x0A);
                        outputFile.WriteByte(0x0A);
                        var subDirNameChar = Encoding.ASCII.GetBytes(sub.Name);
                        outputFile.Write(subDirNameChar, 0, subDirNameChar.Length);
                        var subPfs = new PartitionFileSystem(new FileStorage(root.OpenFile(sub, OpenMode.Read)));
                        foreach (var subPfsFile in subPfs.Files)
                        {
                            outputFile.WriteByte(0x0A);
                            var subPfsFileNameChar = Encoding.ASCII.GetBytes(subPfsFile.Name);
                            outputFile.Write(subPfsFileNameChar, 0, subPfsFileNameChar.Length);
                            using (IFile srcFile = subPfs.OpenFile(subPfsFile.Name, OpenMode.Read))
                            {
                                if (taskType == XciTaskType.extractRomFS && subPfsFile.Name.EndsWith(".nca"))
                                {
                                    var fullOutDirPath = $"{outDirPath}/{sub.Name}/{subPfsFile.Name}";
                                    Out.Log($"Extracting {subPfsFile.Name}...\r\n");
                                    ProcessNca.Extract(srcFile.AsStream(), fullOutDirPath, verifyBeforeDecrypting, keyset, Out);
                                }
                                else
                                {
                                    var destFileName = Path.Combine(sub.Name, subPfsFile.Name);
                                    if (!destFs.DirectoryExists(sub.Name))
                                    {
                                        destFs.CreateDirectory(sub.Name);
                                    }
                                    destFs.CreateFile(destFileName, subPfsFile.Size, CreateFileOptions.None);
                                    using (IFile dstFile = destFs.OpenFile(destFileName, OpenMode.Write))
                                    {
                                        if (taskType == XciTaskType.decrypt && subPfsFile.Name.EndsWith(".nca"))
                                        {
                                            ProcessNca.Process(srcFile, dstFile, verifyBeforeDecrypting, keyset, Out);
                                        }
                                        else
                                        {
                                            srcFile.CopyTo(dstFile);
                                        }
                                    }
                                }
                            }
                        }
                    }

                    outputFile.WriteByte(0x0A);
                    outputFile.Dispose();
                }
        }