Exemple #1
0
        public void Load(System.IO.Stream stream)
        {
            string homeFolder   = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            string KeyFile      = Path.Combine(homeFolder, ".switch", "prod.keys");
            string TitleKeyFile = Path.Combine(homeFolder, ".switch", "title.keys");

            var Keys = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile);

            Stream Input;

            var Pfs       = new Pfs(stream.AsStorage());
            var CnmtNca   = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
            var CnmtPfs   = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true));
            var Cnmt      = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream());
            var Program   = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
            var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);

            if (CtrlEntry != null)
            {
                Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
            }
            Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream();

            var Nca = new Nca(Keys, Input.AsStorage(), true);

            Romfs romfs = new Romfs(
                Nca.OpenSection(Nca.Sections.FirstOrDefault
                                    (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
                                .SectionNum, false, IntegrityCheckLevel.None, true));

            for (int i = 0; i < romfs.Files.Count; i++)
            {
                files.Add(new FileEntry(romfs, romfs.Files[i]));
            }
        }
Exemple #2
0
        public static void ExtractSection(this Nca nca, int index, string outputDir, bool verify = false, IProgressReport logger = null)
        {
            if (index < 0 || index > 3)
            {
                throw new IndexOutOfRangeException();
            }
            if (nca.Sections[index] == null)
            {
                return;
            }

            NcaSection section = nca.Sections[index];
            Stream     stream  = nca.OpenSection(index, false, verify);

            switch (section.Type)
            {
            case SectionType.Invalid:
                break;

            case SectionType.Pfs0:
                var pfs0 = new Pfs(stream);
                pfs0.Extract(outputDir, logger);
                break;

            case SectionType.Romfs:
                var romfs = new Romfs(stream);
                romfs.Extract(outputDir, logger);
                break;

            case SectionType.Bktr:
                break;
            }
        }
Exemple #3
0
        private long OpenNcaFs(ServiceCtx context, string ncaPath, LibHac.IO.IStorage ncaStorage)
        {
            Nca nca = new Nca(context.Device.System.KeySet, ncaStorage, false);

            NcaSection romfsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
            NcaSection pfsSection   = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0);

            if (romfsSection != null)
            {
                LibHac.IO.IStorage romfsStorage  = nca.OpenSection(romfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel, false);
                IFileSystem        ncaFileSystem = new IFileSystem(ncaPath, new RomFsProvider(romfsStorage));

                MakeObject(context, ncaFileSystem);
            }
            else if (pfsSection != null)
            {
                LibHac.IO.IStorage pfsStorage = nca.OpenSection(pfsSection.SectionNum, false, context.Device.System.FsIntegrityCheckLevel, false);
                Pfs         pfs           = new Pfs(pfsStorage);
                IFileSystem ncaFileSystem = new IFileSystem(ncaPath, new PFsProvider(pfs));

                MakeObject(context, ncaFileSystem);
            }
            else
            {
                return(MakeError(ErrorModule.Fs, FsErr.PartitionNotFound));
            }

            return(0);
        }
Exemple #4
0
        private long OpenNcaFs(ServiceCtx Context, string NcaPath, Stream NcaStream)
        {
            Nca Nca = new Nca(Context.Device.System.KeySet, NcaStream, false);

            NcaSection RomfsSection = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs);
            NcaSection PfsSection   = Nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0);

            if (RomfsSection != null)
            {
                Stream      RomfsStream   = Nca.OpenSection(RomfsSection.SectionNum, false, Context.Device.System.FsIntegrityCheckLevel);
                IFileSystem NcaFileSystem = new IFileSystem(NcaPath, new RomFsProvider(RomfsStream));

                MakeObject(Context, NcaFileSystem);
            }
            else if (PfsSection != null)
            {
                Stream      PfsStream     = Nca.OpenSection(PfsSection.SectionNum, false, Context.Device.System.FsIntegrityCheckLevel);
                Pfs         Pfs           = new Pfs(PfsStream);
                IFileSystem NcaFileSystem = new IFileSystem(NcaPath, new PFsProvider(Pfs));

                MakeObject(Context, NcaFileSystem);
            }
            else
            {
                return(MakeError(ErrorModule.Fs, FsErr.PartitionNotFound));
            }

            return(0);
        }
Exemple #5
0
        private long OpenFileSystemFromInternalFile(ServiceCtx context, string fullPath)
        {
            DirectoryInfo archivePath = new DirectoryInfo(fullPath).Parent;

            while (string.IsNullOrWhiteSpace(archivePath.Extension))
            {
                archivePath = archivePath.Parent;
            }

            if (archivePath.Extension == ".nsp" && File.Exists(archivePath.FullName))
            {
                FileStream pfsFile = new FileStream(
                    archivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
                    FileMode.Open,
                    FileAccess.Read);

                Pfs nsp = new Pfs(pfsFile.AsStorage());

                ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet);

                string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\');

                if (nsp.FileExists(filename))
                {
                    return(OpenNcaFs(context, fullPath, nsp.OpenFile(filename)));
                }
            }

            return(MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist));
        }
Exemple #6
0
        public void Load(System.IO.Stream stream)
        {
            var Keys = Forms.SwitchKeySelectionForm.ShowKeySelector();

            if (Keys == null)
            {
                throw new Exception("Failed to get keys. Please select valid paths!");
            }

            var Nca = new Nca(Keys, stream.AsStorage(), true);

            Romfs romfs = new Romfs(
                Nca.OpenSection(Nca.Sections.FirstOrDefault
                                    (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
                                .SectionNum, false, IntegrityCheckLevel.None, true));

            if (Nca.CanOpenSection((int)ProgramPartitionType.Code))
            {
                var exefs = new Pfs(Nca.OpenSection((int)ProgramPartitionType.Code,
                                                    false, IntegrityCheckLevel.None, true));

                foreach (var file in exefs.Files)
                {
                    files.Add(new NSP.ExefsEntry(exefs, file));
                }
            }

            for (int i = 0; i < romfs.Files.Count; i++)
            {
                files.Add(new NSP.FileEntry(romfs, romfs.Files[i]));
            }
        }
Exemple #7
0
        private static string Print(this Pfs pfs)
        {
            const int colLen      = 36;
            const int fileNameLen = 39;

            var sb = new StringBuilder();

            sb.AppendLine();

            sb.AppendLine("PFS0:");

            PrintItem(sb, colLen, "Magic:", pfs.Header.Magic);
            PrintItem(sb, colLen, "Number of files:", pfs.Header.NumFiles);

            for (int i = 0; i < pfs.Files.Length; i++)
            {
                PfsFileEntry file = pfs.Files[i];

                string label   = i == 0 ? "Files:" : "";
                string offsets = $"{file.Offset:x12}-{file.Offset + file.Size:x12}{file.HashValidity.GetValidityString()}";
                string data    = $"pfs0:/{file.Name}".PadRight(fileNameLen) + offsets;

                PrintItem(sb, colLen, label, data);
            }

            return(sb.ToString());
        }
Exemple #8
0
        public void Load(System.IO.Stream stream)
        {
            var Keys = Forms.SwitchKeySelectionForm.ShowKeySelector();

            if (Keys == null)
            {
                throw new Exception("Failed to get keys. Please select valid paths!");
            }

            var Pfs     = new Pfs(stream.AsStorage());
            var CnmtNca = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
            var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true));
            var Cnmt    = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream());

            foreach (var entry in Cnmt.ContentEntries)
            {
                if (entry.Type == CnmtContentType.Program)
                {
                    var    Program     = entry;
                    string ncaFileName = $"{Program.NcaId.ToHexString().ToLower()}.nca";

                    Stream Input = Pfs.OpenFile(ncaFileName).AsStream();
                    var    Nca   = new Nca(Keys, Input.AsStorage(), true);

                    string root = Nca.Header.TitleId.ToString("X");

                    Romfs romfs = new Romfs(
                        Nca.OpenSection(Nca.Sections.FirstOrDefault
                                            (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
                                        .SectionNum, false, IntegrityCheckLevel.None, true));

                    if (Nca.CanOpenSection((int)ProgramPartitionType.Code))
                    {
                        var exefs = new Pfs(Nca.OpenSection((int)ProgramPartitionType.Code,
                                                            false, IntegrityCheckLevel.None, true));

                        foreach (var file in exefs.Files)
                        {
                            files.Add(new ExefsEntry(exefs, file, root));
                        }
                    }

                    for (int i = 0; i < romfs.Files.Count; i++)
                    {
                        files.Add(new FileEntry(romfs, romfs.Files[i], root));
                    }
                }
            }
            var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);

            if (CtrlEntry != null)
            {
                Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
            }
        }
Exemple #9
0
 public ExefsEntry(Pfs pfs, PfsFileEntry entry, string root = "") : base(pfs, entry)
 {
     if (root != string.Empty)
     {
         FileName = $"{root}/Exefs/{entry.Name}";
     }
     else
     {
         FileName = $"Exefs/{entry.Name}";
     }
 }
Exemple #10
0
        private void ImportTitleKeysFromNsp(Pfs nsp, Keyset keySet)
        {
            foreach (PfsFileEntry ticketEntry in nsp.Files.Where(x => x.Name.EndsWith(".tik")))
            {
                Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry).AsStream());

                if (!keySet.TitleKeys.ContainsKey(ticket.RightsId))
                {
                    keySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(keySet));
                }
            }
        }
Exemple #11
0
        private void DrawPfsPages(PaintEventArgs e)
        {
            if (Pfs != null)
            {
                for (var i = 0; i < (VisibleExtents * 8) && i + (WindowPosition * 8) < ExtentCount * 8; i++)
                {
                    var pageId = i + (WindowPosition * 8);

                    pfsRenderer.DrawPfsPage(e.Graphics, PagePosition(i), Pfs.PagePfsByte(pageId));
                }
            }
        }
Exemple #12
0
        public static void Process(Context ctx)
        {
            using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.Read))
            {
                Pfs pfs = new Pfs(file);
                ctx.Logger.LogMessage(pfs.Print());

                if (ctx.Options.OutDir != null)
                {
                    pfs.Extract(ctx.Options.OutDir, ctx.Logger);
                }
            }
        }
Exemple #13
0
        private long OpenNsp(ServiceCtx context, string pfsPath)
        {
            FileStream pfsFile = new FileStream(pfsPath, FileMode.Open, FileAccess.Read);
            Pfs        nsp     = new Pfs(pfsFile.AsStorage());

            ImportTitleKeysFromNsp(nsp, context.Device.System.KeySet);


            IFileSystem nspFileSystem = new IFileSystem(pfsPath, new PFsProvider(nsp));

            MakeObject(context, nspFileSystem);

            return(0);
        }
Exemple #14
0
        public void LoadNsp(string NspFile)
        {
            FileStream File = new FileStream(NspFile, FileMode.Open, FileAccess.Read);

            Pfs Nsp = new Pfs(File);

            PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

            // Load title key from the NSP's ticket in case the user doesn't have a title key file
            if (TicketFile != null)
            {
                // todo Change when Ticket(Stream) overload is added
                Ticket Ticket = new Ticket(new BinaryReader(Nsp.OpenFile(TicketFile)));

                KeySet.TitleKeys[Ticket.RightsId] = Ticket.GetTitleKey(KeySet);
            }

            Nca MainNca    = null;
            Nca ControlNca = null;

            foreach (PfsFileEntry NcaFile in Nsp.Files.Where(x => x.Name.EndsWith(".nca")))
            {
                Nca Nca = new Nca(KeySet, Nsp.OpenFile(NcaFile), true);

                if (Nca.Header.ContentType == ContentType.Program)
                {
                    MainNca = Nca;
                }
                else if (Nca.Header.ContentType == ContentType.Control)
                {
                    ControlNca = Nca;
                }
            }

            if (MainNca != null)
            {
                LoadNca(MainNca, ControlNca);

                return;
            }

            Device.Log.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file");
        }
Exemple #15
0
        public void LoadNsp(string nspFile)
        {
            FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read);

            Pfs nsp = new Pfs(file);

            PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

            // Load title key from the NSP's ticket in case the user doesn't have a title key file
            if (ticketFile != null)
            {
                Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));

                KeySet.TitleKeys[ticket.RightsId] = ticket.GetTitleKey(KeySet);
            }

            Nca mainNca    = null;
            Nca controlNca = null;

            foreach (PfsFileEntry ncaFile in nsp.Files.Where(x => x.Name.EndsWith(".nca")))
            {
                Nca nca = new Nca(KeySet, nsp.OpenFile(ncaFile), true);

                if (nca.Header.ContentType == ContentType.Program)
                {
                    mainNca = nca;
                }
                else if (nca.Header.ContentType == ContentType.Control)
                {
                    controlNca = nca;
                }
            }

            if (mainNca != null)
            {
                LoadNca(mainNca, controlNca);

                return;
            }

            Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file");
        }
Exemple #16
0
        public void LoadNsp(string nspFile)
        {
            FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read);

            Pfs nsp = new Pfs(file.AsStorage(false));

            foreach (PfsFileEntry ticketEntry in nsp.Files.Where(x => x.Name.EndsWith(".tik")))
            {
                Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry).AsStream());

                if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
                {
                    KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet));
                }
            }

            Nca mainNca    = null;
            Nca controlNca = null;

            foreach (PfsFileEntry ncaFile in nsp.Files.Where(x => x.Name.EndsWith(".nca")))
            {
                Nca nca = new Nca(KeySet, nsp.OpenFile(ncaFile), true);

                if (nca.Header.ContentType == ContentType.Program)
                {
                    mainNca = nca;
                }
                else if (nca.Header.ContentType == ContentType.Control)
                {
                    controlNca = nca;
                }
            }

            if (mainNca != null)
            {
                LoadNca(mainNca, controlNca);

                return;
            }

            Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file");
        }
Exemple #17
0
        private long OpenNsp(ServiceCtx context, string pfsPath)
        {
            FileStream   pfsFile    = new FileStream(pfsPath, FileMode.Open, FileAccess.Read);
            Pfs          nsp        = new Pfs(pfsFile);
            PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

            if (ticketFile != null)
            {
                Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));

                context.Device.System.KeySet.TitleKeys[ticket.RightsId] =
                    ticket.GetTitleKey(context.Device.System.KeySet);
            }

            IFileSystem nspFileSystem = new IFileSystem(pfsPath, new PFsProvider(nsp));

            MakeObject(context, nspFileSystem);

            return(0);
        }
Exemple #18
0
        private long OpenNsp(ServiceCtx Context, string PfsPath)
        {
            FileStream   PfsFile    = new FileStream(PfsPath, FileMode.Open, FileAccess.Read);
            Pfs          Nsp        = new Pfs(PfsFile);
            PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

            if (TicketFile != null)
            {
                Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));

                Context.Device.System.KeySet.TitleKeys[Ticket.RightsId] =
                    Ticket.GetTitleKey(Context.Device.System.KeySet);
            }

            IFileSystem NspFileSystem = new IFileSystem(PfsPath, new PFsProvider(Nsp));

            MakeObject(Context, NspFileSystem);

            return(0);
        }
Exemple #19
0
        private long OpenFileSystemFromInternalFile(ServiceCtx context, string fullPath)
        {
            DirectoryInfo archivePath = new DirectoryInfo(fullPath).Parent;

            while (string.IsNullOrWhiteSpace(archivePath.Extension))
            {
                archivePath = archivePath.Parent;
            }

            if (archivePath.Extension == ".nsp" && File.Exists(archivePath.FullName))
            {
                FileStream pfsFile = new FileStream(
                    archivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
                    FileMode.Open,
                    FileAccess.Read);

                Pfs          nsp        = new Pfs(pfsFile);
                PfsFileEntry ticketFile = nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

                if (ticketFile != null)
                {
                    Ticket ticket = new Ticket(nsp.OpenFile(ticketFile));

                    context.Device.System.KeySet.TitleKeys[ticket.RightsId] =
                        ticket.GetTitleKey(context.Device.System.KeySet);
                }

                string filename = fullPath.Replace(archivePath.FullName, string.Empty).TrimStart('\\');

                if (nsp.FileExists(filename))
                {
                    return(OpenNcaFs(context, fullPath, nsp.OpenFile(filename)));
                }
            }

            return(MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist));
        }
Exemple #20
0
        private long OpenFileSystemFromInternalFile(ServiceCtx Context, string FullPath)
        {
            DirectoryInfo ArchivePath = new DirectoryInfo(FullPath).Parent;

            while (string.IsNullOrWhiteSpace(ArchivePath.Extension))
            {
                ArchivePath = ArchivePath.Parent;
            }

            if (ArchivePath.Extension == ".nsp" && File.Exists(ArchivePath.FullName))
            {
                FileStream PfsFile = new FileStream(
                    ArchivePath.FullName.TrimEnd(Path.DirectorySeparatorChar),
                    FileMode.Open,
                    FileAccess.Read);

                Pfs          Nsp        = new Pfs(PfsFile);
                PfsFileEntry TicketFile = Nsp.Files.FirstOrDefault(x => x.Name.EndsWith(".tik"));

                if (TicketFile != null)
                {
                    Ticket Ticket = new Ticket(Nsp.OpenFile(TicketFile));

                    Context.Device.System.KeySet.TitleKeys[Ticket.RightsId] =
                        Ticket.GetTitleKey(Context.Device.System.KeySet);
                }

                string Filename = FullPath.Replace(ArchivePath.FullName, string.Empty).TrimStart('\\');

                if (Nsp.FileExists(Filename))
                {
                    return(OpenNcaFs(Context, FullPath, Nsp.OpenFile(Filename)));
                }
            }

            return(MakeError(ErrorModule.Fs, FsErr.PathDoesNotExist));
        }
Exemple #21
0
 public PartEntry(Pfs pfs, PfsFileEntry entry)
 {
     ParentPfs = pfs;
     fileEntry = entry;
     FileName  = fileEntry.Name;
 }
Exemple #22
0
        static void Main(string[] args)
        {
            Console.WriteLine("Nintendo Switch NSP Verifier v1.00");
            Console.WriteLine("Copyright 2018 CaitSith2");
            Console.WriteLine("");

            _path = args.Length >= 1
                ? string.Join(" ", args)
                : Environment.CurrentDirectory;

            if (new[] { "--help", "-h" }.Any(x => x.Equals(_path, StringComparison.InvariantCultureIgnoreCase)))
            {
                Console.WriteLine("Usage: NSPVerify [path to NSP directory]");
                Console.WriteLine("");
                Console.WriteLine("If the tool is run without specifying a path, it will look for NSPs in the current directory and ALL sub-directories of current directory");
                return;
            }



            if (!Directory.Exists(_path))
            {
                Console.WriteLine("ERROR: Specified directory does not exist.  specify --help for usage information.");
                return;
            }

            var fs = new FileSystem(_path);

            var keys = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch", "prod.keys");

            if (File.Exists("keys.txt"))
            {
                keys = "keys.txt";
            }

            if (!File.Exists(keys))
            {
                Console.WriteLine($"Cannot verify NSPs without keys.txt. Either put it in the same directory as this tool,");
                Console.WriteLine($"or place it in \"{Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch")}\" named as prod.keys");
                PressAnyKey();
                return;
            }

            var keyset        = ExternalKeys.ReadKeyFile(keys);
            var badlist       = new List <string>();
            var exceptionlist = new List <string>();

            var files = fs.GetFileSystemEntries("", "*.nsp", SearchOption.AllDirectories).ToList();

            files.AddRange(fs.GetFileSystemEntries("", "*.nsx", SearchOption.AllDirectories));

            if (files.Count == 0)
            {
                Console.WriteLine("Error: No NSP/NSX files in specified directory");
                PressAnyKey();
                return;
            }

            foreach (var file in files)
            {
                var filename         = Path.GetFileName(file);
                var relativefilename = Util.GetRelativePath(file, Path.GetFullPath(_path));
                Console.Write($"Checking {filename}: ");
                try
                {
                    bool ok = true;
                    using (var nspfile = fs.OpenFile(file, FileMode.Open, FileAccess.Read))
                    {
                        var nspdata  = new Pfs(nspfile);
                        var cnmtfile = nspdata.Files.FirstOrDefault(x => x.Name.ToLowerInvariant().EndsWith(".cnmt.nca"));
                        if (cnmtfile == null)
                        {
                            Console.WriteLine($"\rChecking {filename}: No cnmt.nca file present");
                            badlist.Add(relativefilename);
                            continue;
                        }

                        var  cnmtdata = nspdata.OpenFile(cnmtfile);
                        Cnmt cnmt;
                        using (var sr = new BinaryReader(cnmtdata))
                        {
                            var cnmthash = SHA256.Create().ComputeHash(sr.ReadBytes((int)cnmtdata.Length));
                            if (!cnmtfile.Name.ToLowerInvariant().Contains(cnmthash.Take(16).ToArray().ToHexString()))
                            {
                                //Put failure here
                                Console.WriteLine($"\rChecking {filename}: cnmt.nca file is corrupted");
                                badlist.Add(relativefilename);
                                cnmtdata.Dispose();
                                continue;
                            }

                            cnmtdata.Position = 0;
                            var cnmtnca    = new Nca(keyset, cnmtdata, false);
                            var section    = cnmtnca.OpenSection(0, false);
                            var sectionpfs = new Pfs(section);
                            cnmt = new Cnmt(sectionpfs.OpenFile(sectionpfs.Files[0]));
                        }

                        foreach (var entry in cnmt.ContentEntries)
                        {
                            var entryfile = nspdata.Files.FirstOrDefault(x => x.Name.ToLowerInvariant().EndsWith(entry.NcaId.ToHexString() + ".nca"));
                            if (entryfile == null)
                            {
                                if (entry.Type != CnmtContentType.UpdatePatch)
                                {
                                    //Put failure here
                                    Console.WriteLine($"\rChecking {filename}: one of the entries required by the cnmt.nca is missing.");
                                    badlist.Add(relativefilename);
                                    break;
                                }

                                continue;
                            }

                            using (var entrynca = nspdata.OpenFile(entryfile))
                            {
                                var hash = SHA256.Create();

                                using (var sr = new BinaryReader(entrynca))
                                {
                                    while (entrynca.Length != entrynca.Position)
                                    {
                                        var entryncadata = sr.ReadBytes(0x100000);
                                        hash.TransformBlock(entryncadata, 0, entryncadata.Length, entryncadata, 0);
                                        Console.Write($"\rChecking {filename}: {((entrynca.Position * 100.0) / entrynca.Length):0.0}%");
                                    }

                                    hash.TransformFinalBlock(new byte[0], 0, 0);
                                }

                                if (hash.Hash.ToHexString().Equals(entry.Hash.ToHexString()))
                                {
                                    Console.Write($"\rChecking {filename}: {100:0.0}%");
                                    continue;
                                }

                                //Put failure here
                                Console.WriteLine($"\rChecking {filename}: one of the entries required by the cnmt.nca is corrupted");
                                badlist.Add(relativefilename);
                                ok = false;
                                break;
                            }
                        }

                        if (ok)
                        {
                            Console.WriteLine($"\rChecking {filename}: OK        ");
                        }
                        //Put Success here
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                    exceptionlist.Add($"{relativefilename}{Environment.NewLine}Exception: \"{ex.GetType()}\" {ex.Message}{Environment.NewLine}Stack Trace: {ex.StackTrace}{Environment.NewLine}");
                }
            }

            badlist.Insert(0, badlist.Count == 0
                ? "None of the files are corrupted. :)"
                : "The following NSP/NSX files are corrupted:");

            exceptionlist.Insert(0, exceptionlist.Count == 0
                ? "No exceptions to log. :)"
                : "Exceptions caused while parsing the following NSP/NSX files:");

            try
            {
                File.WriteAllText("Corrupted NSPs.txt", string.Join(Environment.NewLine, badlist));
                File.WriteAllText("Exception Log.txt", string.Join(Environment.NewLine, exceptionlist));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Could not write the output files \"Corrupted NSPs.txt\" and \"Exception Log.txt\" due to the following exception.");
                Console.WriteLine($"Exception: \"{ex.GetType()}\" {ex.Message}");
                Console.WriteLine($"Stack Trace: {ex.StackTrace}{Environment.NewLine}");

                Console.WriteLine(string.Join(Environment.NewLine, badlist));
                Console.WriteLine();
                Console.WriteLine(string.Join(Environment.NewLine, exceptionlist));
                Console.WriteLine();
            }

            Console.WriteLine("Done.");
            PressAnyKey();
        }
Exemple #23
0
        //Open update only
        private void Open_NSP_Update(object sender, EventArgs e)
        {
            var Dialog = openFileDialog1.ShowDialog();

            if (Dialog != DialogResult.Cancel)
            {
                Console.WriteLine("LOADING.");
                label8.Visible = true;
                this.Update();
                treeView1.Nodes.Clear();

                string FileToOpen = null;

                if (Program.FileArg != null)
                {
                    FileToOpen = Program.FileArg;
                }
                else
                {
                    FileToOpen = openFileDialog1.FileName;
                }

                Program.FileArg = null;
                Stream Input = null;

                try
                {
                    string ExpEnv(string In) => Environment.ExpandEnvironmentVariables(In);

                    var ProdKeys  = ExpEnv(@"%USERPROFILE%\.switch\prod.keys");
                    var TitleKeys = ExpEnv(@"%USERPROFILE%\.switch\title.keys");
                    Console.WriteLine(FileToOpen);

                    var Keys = ExternalKeys.ReadKeyFile(ProdKeys, TitleKeys);

                    var Ext = (new FileInfo(FileToOpen).Extension);
                    if (Ext == ".nsp")
                    {
                        var InputPFS  = File.OpenRead(FileToOpen);
                        var Pfs       = new Pfs(InputPFS.AsStorage());
                        var CnmtNca   = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
                        var CnmtPfs   = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true));
                        var Cnmt      = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream());
                        var Program   = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
                        var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
                        if (CtrlEntry != null)
                        {
                            Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
                        }
                        Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream();
                    }
                    else
                    {
                        Input = File.OpenRead(FileToOpen);
                    }

                    try
                    {
                        Nca = new Nca(Keys, Input.AsStorage(), true);

                        if (Nca.HasRightsId && !Keys.TitleKeys.Keys.Any(k => k.SequenceEqual(Nca.Header.RightsId)))
                        {
                            MessageBox.Show($"Error: the titlekey for {Nca.Header.RightsId.ToHexString().ToLower()} is not present in your key file.");
                        }
                        else
                        {
                            var isUpdateNca = false;

                            if (Nca.Sections.Any(s => s?.Type == SectionType.Bktr))
                            {
                                isUpdateNca = true;
                            }

                            if (isUpdateNca)
                            {
                                var InputPFS  = File.OpenRead(FileToOpen);
                                var Pfs       = new Pfs(InputPFS.AsStorage());
                                var CnmtNca   = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
                                var CnmtPfs   = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true));
                                var Cnmt      = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream());
                                var Program   = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
                                var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
                                if (CtrlEntry != null)
                                {
                                    Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
                                }
                                Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream();

                                var Input2 = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream();
                                Patch = new Nca(Keys, Input2.AsStorage(), true);
                                Nca.SetBaseNca(Patch);
                            }

                            new Thread
                                (() =>
                            {
                                Thread.CurrentThread.IsBackground = true;
                                var Info = GetTitleMeta($"{Nca.Header.TitleId:x16}");
                                label2.Invoke(new Action(() => { label2.Text = Info[0]; label3.Text = Info[1]; }));
                            }).Start();

                            Rom = new Romfs(
                                Nca.OpenSection(Nca.Sections.FirstOrDefault
                                                    (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
                                                .SectionNum, false, IntegrityCheckLevel.None, true)
                                );

                            IO.PopulateTreeView(treeView1.Nodes, Rom.RootDir);

                            Console.WriteLine("DONE.");
                            fileToolStripMenuItem.Text = "File / Explore";
                            label8.Visible             = false;
                            this.Update();
                        }
                    }
                    catch
                    {
                        MessageBox.Show("There was an error reading the NCA. Are you sure the correct keys are present in your keyfiles?");
                    }
                }
                catch (ArgumentNullException) { MessageBox.Show("Error: key files are missing!"); }
            }
        }
Exemple #24
0
        public void LoadNca(Nca mainNca, Nca controlNca)
        {
            if (mainNca.Header.ContentType != ContentType.Program)
            {
                Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");

                return;
            }

            Stream romfsStream = mainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
            Stream exefsStream = mainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);

            if (exefsStream == null)
            {
                Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");

                return;
            }

            if (romfsStream == null)
            {
                Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
            }
            else
            {
                Device.FileSystem.SetRomFs(romfsStream);
            }

            Pfs exefs = new Pfs(exefsStream);

            Npdm metaData = null;

            if (exefs.FileExists("main.npdm"))
            {
                Logger.PrintInfo(LogClass.Loader, "Loading main.npdm...");

                metaData = new Npdm(exefs.OpenFile("main.npdm"));
            }
            else
            {
                Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");

                metaData = GetDefaultNpdm();
            }

            List <IExecutable> staticObjects = new List <IExecutable>();

            void LoadNso(string filename)
            {
                foreach (PfsFileEntry file in exefs.Files.Where(x => x.Name.StartsWith(filename)))
                {
                    if (Path.GetExtension(file.Name) != string.Empty)
                    {
                        continue;
                    }

                    Logger.PrintInfo(LogClass.Loader, $"Loading {filename}...");

                    NxStaticObject staticObject = new NxStaticObject(exefs.OpenFile(file));

                    staticObjects.Add(staticObject);
                }
            }

            Nacp ReadControlData()
            {
                Romfs controlRomfs = new Romfs(controlNca.OpenSection(0, false, FsIntegrityCheckLevel));

                byte[] controlFile = controlRomfs.GetFile("/control.nacp");

                BinaryReader reader = new BinaryReader(new MemoryStream(controlFile));

                Nacp controlData = new Nacp(reader);

                CurrentTitle = controlData.Languages[(int)State.DesiredTitleLanguage].Title;

                if (string.IsNullOrWhiteSpace(CurrentTitle))
                {
                    CurrentTitle = controlData.Languages.ToList().Find(x => !string.IsNullOrWhiteSpace(x.Title)).Title;
                }

                return(controlData);
            }

            if (controlNca != null)
            {
                ReadControlData();
            }
            else
            {
                CurrentTitle = metaData.Aci0.TitleId.ToString("x16");
            }

            if (!metaData.Is64Bits)
            {
                throw new NotImplementedException("32-bit titles are not supported!");
            }

            LoadNso("rtld");
            LoadNso("main");
            LoadNso("subsdk");
            LoadNso("sdk");

            ContentManager.LoadEntries();

            ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
        }
Exemple #25
0
        public static Title processNsp(string filename)
        {
            Title title = new Title();

            using (var filestream = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                Pfs    pfs;
                string biggestNca = null, controlNca = null;

                try
                {
                    pfs = new Pfs(filestream.AsStorage());

                    title.distribution = Title.Distribution.Digital;

                    log?.WriteLine("Processing NSP {0}", filename);

                    PfsFileEntry[] fileEntries = pfs.Files;
                    foreach (PfsFileEntry entry in fileEntries)
                    {
                        if (entry.Name.EndsWith(".cnmt.xml"))
                        {
                            try
                            {
                                using (var cnmtXml = pfs.OpenFile(entry))
                                {
                                    (biggestNca, controlNca) = processCnmtXml(cnmtXml, ref title);
                                }
                            }
                            catch (FileNotFoundException) { }

                            title.structure.Add(Title.Structure.CnmtXml);
                        }
                        else if (entry.Name.EndsWith(".cnmt.nca"))
                        {
                            try
                            {
                                using (var cnmtNca = pfs.OpenFile(entry))
                                {
                                    var nca = processCnmtNca(cnmtNca, ref title);
                                    if (nca.Item1 != null && (nca.Item2 != null || title.type == TitleType.AddOnContent))
                                    {
                                        (biggestNca, controlNca) = nca;
                                    }
                                }
                            }
                            catch (FileNotFoundException)
                            {
                                if (pfs.FileExists(entry.Name.Replace(".nca", ".ncz")))
                                {
                                    title.error = "Unsupported Format: Compressed NCA";
                                }
                            }

                            title.structure.Add(Title.Structure.CnmtNca);
                        }
                        else if (entry.Name.EndsWith(".cert"))
                        {
                            title.structure.Add(Title.Structure.Cert);
                        }
                        else if (entry.Name.EndsWith(".tik"))
                        {
                            try
                            {
                                using (var tik = pfs.OpenFile(entry))
                                {
                                    if (entry.Name.Split('.')[0].TryToBytes(out byte[] rightsId))
                                    {
                                        processTik(tik, rightsId, ref keyset, out byte[] titleKey);

                                        title.titleKey = BitConverter.ToString(titleKey).Replace("-", "").ToUpper();
                                    }
                                }
                            }
                            catch (FileNotFoundException)
                            {
                                if (pfs.FileExists(entry.Name.Replace(".nca", ".ncz")))
                                {
                                    title.error = "Unsupported Format: Compressed NCA";
                                }
                            }

                            title.structure.Add(Title.Structure.Tik);
                        }
                        else if (entry.Name.EndsWith(".legalinfo.xml"))
                        {
                            title.structure.Add(Title.Structure.LegalinfoXml);
                        }
                        else if (entry.Name.EndsWith(".nacp.xml"))
                        {
                            try
                            {
                                using (var nacpXml = pfs.OpenFile(entry))
                                {
                                    processNacpXml(nacpXml, ref title);
                                }
                            }
                            catch (FileNotFoundException) { }

                            title.structure.Add(Title.Structure.NacpXml);
                        }
                        else if (entry.Name.EndsWith(".programinfo.xml"))
                        {
                            title.structure.Add(Title.Structure.PrograminfoXml);
                        }
                        else if (entry.Name.Equals("cardspec.xml"))
                        {
                            title.structure.Add(Title.Structure.CardspecXml);
                        }
                        else if (entry.Name.Equals("authoringtoolinfo.xml"))
                        {
                            title.structure.Add(Title.Structure.AuthoringtoolinfoXml);
                        }
                    }

                    if (!String.IsNullOrEmpty(biggestNca))
                    {
                        try
                        {
                            using (var biggest = pfs.OpenFile(biggestNca))
                            {
                                processBiggestNca(biggest, ref title);
                            }
                        }
                        catch (FileNotFoundException)
                        {
                            if (pfs.FileExists(biggestNca.Replace(".nca", ".ncz")))
                            {
                                title.error = "Unsupported Format: Compressed NCA";
                            }
                        }
                    }

                    if (!String.IsNullOrEmpty(controlNca))
                    {
                        try
                        {
                            using (var control = pfs.OpenFile(controlNca))
                            {
                                processControlNca(control, ref title);
                            }
                        }
                        catch (FileNotFoundException)
                        {
                            if (pfs.FileExists(controlNca.Replace(".nca", ".ncz")))
                            {
                                title.error = "Unsupported Format: Compressed NCA";
                            }
                        }
                    }
                }
                catch (InvalidDataException)
                {
                    return(null);
                }
            }

            if (title.type == TitleType.Application || title.type == TitleType.Patch)
            {
                if (versionList.TryGetValue(title.baseTitleID, out uint version))
                {
                    title.latestVersion = version;
                }
            }

            log?.WriteLine("NSP information for {0}: [{1}] {2}", filename, title.titleID, title.titleName);

            return(title);
        }
Exemple #26
0
        public void LoadNsp(string nspFile)
        {
            FileStream file = new FileStream(nspFile, FileMode.Open, FileAccess.Read);

            Pfs nsp = new Pfs(file.AsStorage(false));

            foreach (PfsFileEntry ticketEntry in nsp.Files.Where(x => x.Name.EndsWith(".tik")))
            {
                Ticket ticket = new Ticket(nsp.OpenFile(ticketEntry).AsStream());

                if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
                {
                    KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet));
                }
            }

            Nca mainNca    = null;
            Nca controlNca = null;

            foreach (PfsFileEntry ncaFile in nsp.Files.Where(x => x.Name.EndsWith(".nca")))
            {
                Nca nca = new Nca(KeySet, nsp.OpenFile(ncaFile), true);

                if (nca.Header.ContentType == ContentType.Program)
                {
                    mainNca = nca;
                }
                else if (nca.Header.ContentType == ContentType.Control)
                {
                    controlNca = nca;
                }
            }

            if (mainNca != null)
            {
                LoadNca(mainNca, controlNca);

                return;
            }

            // This is not a normal NSP, it's actually a ExeFS as a NSP
            Npdm metaData = null;

            PfsFileEntry npdmFile = nsp.Files.FirstOrDefault(x => x.Name.Equals("main.npdm"));

            if (npdmFile != null)
            {
                Logger.PrintInfo(LogClass.Loader, $"Loading main.npdm...");

                metaData = new Npdm(nsp.OpenFile(npdmFile).AsStream());
            }
            else
            {
                Logger.PrintWarning(LogClass.Loader, $"NPDM file not found, using default values!");

                metaData = GetDefaultNpdm();
            }

            List <IExecutable> staticObjects = new List <IExecutable>();

            void LoadNso(string searchPattern)
            {
                PfsFileEntry entry = nsp.Files.FirstOrDefault(x => x.Name.Equals(searchPattern));

                if (entry != null)
                {
                    Logger.PrintInfo(LogClass.Loader, $"Loading {entry.Name}...");

                    NxStaticObject staticObject = new NxStaticObject(nsp.OpenFile(entry).AsStream());

                    staticObjects.Add(staticObject);
                }
            }

            CurrentTitle = metaData.Aci0.TitleId.ToString("x16");

            LoadNso("rtld");
            LoadNso("main");
            LoadNso("subsdk*");
            LoadNso("sdk");

            ContentManager.LoadEntries();

            if (staticObjects.Count == 0)
            {
                Logger.PrintError(LogClass.Loader, "Could not find an Application NCA in the provided NSP file");
            }
            else
            {
                ProgramLoader.LoadStaticObjects(this, metaData, staticObjects.ToArray());
            }
        }
Exemple #27
0
        public static void Main(string[] Args)
        {
usbnsp:
            Console.Clear();
            Initialize();
            try
            {
                var pat = new KLST_PATTERN_MATCH {
                    DeviceID = @"USB\VID_057E&PID_3000"
                };
                var lst = new LstK(0, ref pat);
                lst.MoveNext(out var dinfo);
                USB = new UsbK(dinfo);
            }
            catch
            {
                Error.Log("No USB connection was found. Make sure you have Goldleaf open before running Goldtree.");
            }
            try
            {
                Command c = new Command(CommandId.ConnectionRequest);
                USB.Write(c);
                Log.Log("Attempting to connect to Goldleaf via USB...");
                Command rc = USB.Read();
                if (rc.MagicOk())
                {
                    if (rc.IsCommandId(CommandId.ConnectionResponse))
                    {
                        Log.Log("Connection was established with Goldleaf.");
                        Log.Log("Select the NSP to send to Goldleaf on the dialog.");
                        OpenFileDialog fd = new OpenFileDialog()
                        {
                            Title       = "Select NSP to send to Goldleaf via USB",
                            Filter      = "NSP / Nintendo Submission Package (*.nsp)|*.nsp",
                            Multiselect = false,
                        };
                        if (fd.ShowDialog() == DialogResult.OK)
                        {
                            string nsp     = fd.FileName;
                            string nspname = Path.GetFileName(nsp);
                            c = new Command(CommandId.NSPName);
                            USB.Write(c);
                            USB.Write((uint)nspname.Length);
                            USB.Write(nspname);
                            Log.Log("Selected NSP's name was sent to Goldleaf. Waiting for install approval from Goldleaf...");
                            Command rc2 = USB.Read();
                            if (rc2.MagicOk())
                            {
                                if (rc2.IsCommandId(CommandId.Start))
                                {
                                    Log.Log("Goldleaf is ready for the installation. Preparing everything...");
                                    try
                                    {
                                        FileStream    fs   = new FileStream(nsp, FileMode.Open);
                                        StreamStorage ist  = new StreamStorage(fs, true);
                                        Pfs           pnsp = new Pfs(ist);
                                        ist.Dispose();
                                        fs.Close();
                                        fs = new FileStream(nsp, FileMode.Open);
                                        uint filecount = (uint)pnsp.Files.Length;
                                        c = new Command(CommandId.NSPData);
                                        USB.Write(c);
                                        USB.Write(filecount);
                                        int tikidx  = -1;
                                        int certidx = -1;
                                        int tmpidx  = 0;
                                        foreach (var file in pnsp.Files)
                                        {
                                            ulong offset = (ulong)pnsp.HeaderSize + (ulong)file.Offset;
                                            ulong size   = (ulong)file.Size;
                                            uint  len    = (uint)file.Name.Length;
                                            USB.Write(len);
                                            USB.Write(file.Name);
                                            USB.Write(offset);
                                            USB.Write(size);
                                            if (Path.GetExtension(file.Name).Replace(".", "").ToLower() == "tik")
                                            {
                                                tikidx = tmpidx;
                                            }
                                            else if (Path.GetExtension(file.Name).Replace(".", "").ToLower() == "cert")
                                            {
                                                certidx = tmpidx;
                                            }
                                            tmpidx++;
                                        }
                                        BinaryReader br = new BinaryReader(fs);
                                        while (true)
                                        {
                                            Command ccmd = USB.Read();
                                            if (ccmd.MagicOk())
                                            {
                                                if (ccmd.IsCommandId(CommandId.NSPContent))
                                                {
                                                    USB.Read(out uint idx);
                                                    Log.Log("Sending content \'" + pnsp.Files[idx].Name + "\'... (" + (idx + 1) + " of " + pnsp.Files.Length + ")");
                                                    PfsFileEntry ent     = pnsp.Files[idx];
                                                    long         rsize   = 0x800000;
                                                    long         coffset = pnsp.HeaderSize + ent.Offset;
                                                    long         toread  = ent.Size;
                                                    long         tmpread = 1;
                                                    byte[]       bufb;
                                                    while ((tmpread > 0) && (toread > 0) && (coffset < (coffset + ent.Size)))
                                                    {
                                                        if (rsize >= ent.Size)
                                                        {
                                                            rsize = ent.Size;
                                                        }
                                                        int tor = (int)Math.Min(rsize, toread);
                                                        br.BaseStream.Position = coffset;
                                                        bufb    = br.ReadBytes(tor);
                                                        tmpread = bufb.Length;
                                                        USB.Write(bufb);
                                                        coffset += tmpread;
                                                        toread  -= tmpread;
                                                    }
                                                    Log.Log("Content was sent to Goldleaf.");
                                                }
                                                else if (ccmd.IsCommandId(CommandId.NSPTicket))
                                                {
                                                    Log.Log("Sending ticket file...");
                                                    PfsFileEntry tik = pnsp.Files[tikidx];
                                                    br.BaseStream.Seek(pnsp.HeaderSize + tik.Offset, SeekOrigin.Begin);
                                                    byte[] file = br.ReadBytes((int)tik.Size);
                                                    USB.Write(file);
                                                    Log.Log("Ticket was sent to Goldleaf.");
                                                }
                                                else if (ccmd.IsCommandId(CommandId.Finish))
                                                {
                                                    break;
                                                }
                                                else
                                                {
                                                    USB = null;
                                                    Error.Log("An invalid command was received. Are you sure Goldleaf is active?");
                                                }
                                            }
                                            else
                                            {
                                                USB = null;
                                                Error.Log("An invalid command was received. Are you sure Goldleaf is active?");
                                            }
                                        }
                                    }
                                    catch
                                    {
                                        Error.Log("An error ocurred opening the selected NSP. Are you sure it's a valid NSP?");
                                    }
                                }
                                else if (rc2.IsCommandId(CommandId.Finish))
                                {
                                    USB = null;
                                    Error.Log("Goldleaf has canceled the installation.");
                                }
                                else
                                {
                                    USB = null;
                                    Error.Log("An invalid command was received. Are you sure Goldleaf is active?");
                                }
                            }
                            else
                            {
                                USB = null;
                                Error.Log("An invalid command was received. Are you sure Goldleaf is active?");
                            }
                        }
                        else
                        {
                            Error.Log("The dialog was closed without selecting a NSP, or another error ocurred. Reopen Goldleaf and Goldtree and try again.");
                        }
                    }
                    else if (rc.IsCommandId(CommandId.Finish))
                    {
                        USB = null;
                        Error.Log("Goldleaf has canceled the installation.");
                    }
                    else
                    {
                        USB = null;
                        Error.Log("An invalid command was received. Are you sure Goldleaf is active?");
                    }
                }
                else
                {
                    USB = null;
                    Error.Log("An invalid command was received. Are you sure Goldleaf is active?");
                }
            }
            catch
            {
                Error.Log("An error ocurred selecting the NSP to be sent.");
            }
            Log.Log("The installation has finished. Press ENTER to close Goldtree, or any other key to start another USB installation.", true);
            ConsoleKeyInfo ki = Console.ReadKey();

            if (ki.Key == ConsoleKey.Enter)
            {
                if (USB != null)
                {
                    Command cmd = new Command(CommandId.Finish);
                    USB.Write(cmd);
                }
                Environment.Exit(0);
            }
            else
            {
                goto usbnsp;
            }
        }
Exemple #28
0
        private static (string, string) processCnmtNca(Nca nca, ref Title title, bool cnmtContent = true)
        {
            string biggestNca = null, controlNca = null;

            log?.WriteLine("Processing CNMT NCA");

            try
            {
                Pfs ncaPfs = new Pfs(nca.OpenSection(0, false, IntegrityCheckLevel.ErrorOnInvalid, true));

                PfsFileEntry[] ncaFileEntries = ncaPfs.Files;
                foreach (PfsFileEntry pfsEntry in ncaFileEntries)
                {
                    Cnmt cnmt = new Cnmt(ncaPfs.OpenFile(pfsEntry).AsStream());

                    if (title.version == unchecked ((uint)-1) || cnmt.TitleVersion?.Version > title.version)
                    {
                        title.type = cnmt.Type;

                        title.titleID     = String.Format("{0:X16}", cnmt.TitleId);
                        title.baseTitleID = String.Format("{0:X16}", cnmt.ApplicationTitleId);
                        title.version     = cnmt.TitleVersion?.Version ?? title.version;

                        title.systemVersion      = cnmt.MinimumSystemVersion?.Version ?? unchecked ((uint)-1);
                        title.applicationVersion = cnmt.MinimumApplicationVersion?.Version ?? unchecked ((uint)-1);

                        if (cnmtContent)
                        {
                            CnmtContentEntry[] contentEntries = cnmt.ContentEntries;
                            foreach (CnmtContentEntry contentEntry in contentEntries)
                            {
                                if (title.type == TitleType.Application || title.type == TitleType.Patch)
                                {
                                    if (contentEntry.Type == CnmtContentType.Program)
                                    {
                                        biggestNca = BitConverter.ToString(contentEntry.NcaId).Replace("-", "").ToLower() + ".nca";

                                        log?.WriteLine("Found Biggest NCA {0}", biggestNca);
                                    }
                                    else if (contentEntry.Type == CnmtContentType.Control)
                                    {
                                        controlNca = BitConverter.ToString(contentEntry.NcaId).Replace("-", "").ToLower() + ".nca";

                                        log?.WriteLine("Found Control NCA {0}", controlNca);
                                    }
                                }
                                else if (title.type == TitleType.AddOnContent)
                                {
                                    if (contentEntry.Type == CnmtContentType.Data)
                                    {
                                        biggestNca = BitConverter.ToString(contentEntry.NcaId).Replace("-", "").ToLower() + ".nca";

                                        log?.WriteLine("Found Biggest NCA {0}", biggestNca);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (MissingKeyException ex)
            {
                title.error = String.Format("Missing {0}: {1}", ex.Type == KeyType.Title ? "Title Key" : "Key", ex.Name.Replace("key_area_key_application", "master_key"));

                log?.WriteLine(title.error);
            }
            catch (FileNotFoundException) { }

            return(biggestNca, controlNca);
        }
Exemple #29
0
        private void Open()
        {
            treeView1.Nodes.Clear();

            string FileToOpen = null;

            if (Program.FileArg != null)
            {
                FileToOpen = Program.FileArg;
            }
            else
            {
                FileToOpen = openFileDialog1.FileName;
            }

            Program.FileArg = null;
            Stream Input = null;

            try
            {
                string ExpEnv(string In) => Environment.ExpandEnvironmentVariables(In);

                var ProdKeys  = ExpEnv(@"%USERPROFILE%\.switch\prod.keys");
                var TitleKeys = ExpEnv(@"%USERPROFILE%\.switch\title.keys");

                var Keys = ExternalKeys.ReadKeyFile(ProdKeys, TitleKeys);

                var Ext = (new FileInfo(FileToOpen).Extension);

                if (Ext == ".nsp")
                {
                    var InputPFS  = File.OpenRead(FileToOpen);
                    var Pfs       = new Pfs(InputPFS);
                    var CnmtNca   = new Nca(Keys, Pfs.OpenFile(Pfs.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
                    var CnmtPfs   = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None));
                    var Cnmt      = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]));
                    var Program   = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
                    var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
                    if (CtrlEntry != null)
                    {
                        Control = new Nca(Keys, Pfs.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
                    }
                    Input = Pfs.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca");
                }
                else if (Ext == ".xci")
                {
                    var InputPFS  = File.OpenRead(FileToOpen);
                    var Xci       = new Xci(Keys, InputPFS);
                    var CnmtNca   = new Nca(Keys, Xci.SecurePartition.OpenFile(Xci.SecurePartition.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
                    var CnmtPfs   = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None));
                    var Cnmt      = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]));
                    var Program   = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
                    var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
                    if (CtrlEntry != null)
                    {
                        Control = new Nca(Keys, Xci.SecurePartition.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
                    }
                    Input = Xci.SecurePartition.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca");
                }
                else if (FileToOpen.Split('.')[1] == "cnmt" && Ext == ".nca")
                {
                    var TargetFile = File.OpenRead(FileToOpen);
                    var CnmtNca    = new Nca(Keys, TargetFile, false);
                    var CnmtPfs    = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None));
                    var Cnmt       = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]));
                    var Program    = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
                    var CtrlEntry  = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
                    if (CtrlEntry != null)
                    {
                        Control = new Nca(Keys, File.OpenRead($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
                    }
                    Input = File.OpenRead($"{Program.NcaId.ToHexString().ToLower()}.nca");
                }
                else
                {
                    Input = File.OpenRead(FileToOpen);
                }

                try
                {
                    Nca = new Nca(Keys, Input, true);

                    if (Nca.HasRightsId && !Keys.TitleKeys.Keys.Any(k => k.SequenceEqual(Nca.Header.RightsId)))
                    {
                        MessageBox.Show($"Error: the titlekey for {Nca.Header.RightsId.ToHexString().ToLower()} is not present in your key file.");
                    }
                    else
                    {
                        bool isUpdateNca = false;

                        if (Nca.Sections.Any(s => s?.Type == SectionType.Bktr))
                        {
                            isUpdateNca = true;
                        }

                        if (isUpdateNca)
                        {
                            openFileDialog1.Title = "Select base Nca";
                            openFileDialog1.ShowDialog();
                            var Input2 = File.OpenRead(openFileDialog1.FileName);
                            Patch = new Nca(Keys, Input2, true);
                            Nca.SetBaseNca(Patch);
                        }

                        new Thread
                        (
                            () =>
                        {
                            Thread.CurrentThread.IsBackground = true;
                            var Info = GetTitleMeta($"{Nca.Header.TitleId:x16}");

                            label2.Invoke(new Action(() => { label2.Text = Info[0]; label3.Text = Info[1]; }));
                        }
                        )
                        .Start();

                        Rom = new Romfs
                              (
                            Nca.OpenSection
                            (
                                Nca.Sections.FirstOrDefault
                                    (s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
                                .SectionNum,
                                false,
                                IntegrityCheckLevel.None
                            )
                              );

                        IO.PopulateTreeView(treeView1.Nodes, Rom.RootDir);
                    }
                }
                catch
                {
                    MessageBox.Show("There was an error reading the NCA. Are you sure the correct keys are present in your keyfiles?");
                }
            }
            catch (ArgumentNullException)
            {
                MessageBox.Show("Error: key files are missing!");
            }
        }
Exemple #30
0
 public ExefsEntry(Pfs pfs, PfsFileEntry entry)
 {
     ParentPfs = pfs;
     fileEntry = entry;
     FileName  = $"Exefs/{fileEntry.Name}";
 }