Exemplo n.º 1
0
        public Result UnregisterAllExternalKey()
        {
            ExternalKeys.Clear();

            return(Result.Success);
        }
Exemplo n.º 2
0
 public Result RegisterExternalKey(ref RightsId rightsId, ref AccessKey externalKey)
 {
     return(ExternalKeys.Add(rightsId, externalKey));
 }
Exemplo n.º 3
0
        public Result UnregisterExternalKey(ref RightsId rightsId)
        {
            ExternalKeys.Remove(rightsId);

            return(Result.Success);
        }
Exemplo n.º 4
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!"); }
            }
        }
Exemplo n.º 5
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!");
            }
        }
Exemplo n.º 6
0
        public static bool initialize(out List <string> messages)
        {
            messages = new List <string>();

            string prod_keys    = path_prefix + Common.PROD_KEYS;
            string title_keys   = path_prefix + Common.TITLE_KEYS;
            string console_keys = path_prefix + Common.CONSOLE_KEYS;

            if (!File.Exists(prod_keys))
            {
                messages.Add("File not found. Check if '" + Common.PROD_KEYS + "' exist and try again.");
                return(false);
            }

            if (Common.Settings.Default.DebugLog)
            {
                try
                {
                    log           = File.AppendText(path_prefix + Common.LOG_FILE);
                    log.AutoFlush = true;
                }
                catch { }
            }

            log?.WriteLine("--------------------------------------------------------------");
            log?.WriteLine("Application starts at {0}\n", String.Format("{0:F}", DateTime.Now));

            try
            {
                log?.WriteLine("Reading keys");
                log?.WriteLine(" - {0} ({1}exists)", prod_keys, File.Exists(prod_keys) ? "" : "not ");
                log?.WriteLine(" - {0} ({1}exists)", title_keys, File.Exists(title_keys) ? "" : "not ");
                log?.WriteLine(" - {0} ({1}exists)", console_keys, File.Exists(console_keys) ? "" : "not ");

                keyset = ExternalKeys.ReadKeyFile(prod_keys, title_keys, console_keys);

                log?.WriteLine("Found {0} title keys", keyset?.TitleKeys?.Count);

                titleNames    = keyset.TitleNames.ToDictionary(p => BitConverter.ToString(p.Key.Take(8).ToArray()).Replace("-", "").ToUpper(), p => p.Value);
                titleVersions = keyset.TitleVersions.ToDictionary(p => BitConverter.ToString(p.Key.Take(8).ToArray()).Replace("-", "").ToUpper(), p => p.Value);
            }
            catch { }

            try
            {
                if (!(bool)keyset?.HeaderKey?.Any(b => b != 0) ||
                    !(bool)keyset?.AesKekGenerationSource?.Any(b => b != 0) || !(bool)keyset?.AesKeyGenerationSource?.Any(b => b != 0) || !(bool)keyset?.KeyAreaKeyApplicationSource?.Any(b => b != 0) ||
                    !((bool)keyset?.MasterKeys?[0]?.Any(b => b != 0) || (bool)keyset?.KeyAreaKeys?[0]?[0]?.Any(b => b != 0)))
                {
                    log?.WriteLine("Keyfile missing required keys");
                    log?.WriteLine(" - {0} ({1}exists)", "header_key", (bool)keyset?.HeaderKey?.Any(b => b != 0) ? "" : "not ");
                    log?.WriteLine(" - {0} ({1}exists)", "aes_kek_generation_source", (bool)keyset?.AesKekGenerationSource?.Any(b => b != 0) ? "" : "not ");
                    log?.WriteLine(" - {0} ({1}exists)", "aes_key_generation_source", (bool)keyset?.AesKeyGenerationSource?.Any(b => b != 0) ? "" : "not ");
                    log?.WriteLine(" - {0} ({1}exists)", "key_area_key_application_source", (bool)keyset?.KeyAreaKeyApplicationSource?.Any(b => b != 0) ? "" : "not ");
                    log?.WriteLine(" - {0} ({1}exists)", "master_key_00", (bool)keyset?.MasterKeys[0]?.Any(b => b != 0) ? "" : "not ");
                    log?.WriteLine(" - {0} ({1}exists)", "key_area_key_application_00", (bool)keyset?.KeyAreaKeys[0][0]?.Any(b => b != 0) ? "" : "not ");

                    messages.Add("Keyfile missing required keys. Check if these keys exist and try again.\n" +
                                 "header_key, aes_kek_generation_source, aes_key_generation_source, key_area_key_application_source, master_key_00 or key_area_key_application_00.");
                    return(false);
                }
            }
            catch
            {
                messages.Add("Keyfile missing required keys. Check if these keys exist and try again.\n" +
                             "header_key, aes_kek_generation_source, aes_key_generation_source, key_area_key_application_source, master_key_00 or key_area_key_application_00.");
                return(false);
            }

            string hac_versionlist = path_prefix + Common.HAC_VERSIONLIST;

            try
            {
                log?.WriteLine("Reading version list");

                var versionlist = JsonConvert.DeserializeObject <Common.VersionList>(File.ReadAllText(hac_versionlist));

                foreach (var title in versionlist.titles)
                {
                    string titleID = title.id;
                    if (titleID.EndsWith("800"))
                    {
                        titleID = titleID.Substring(0, Math.Min(titleID.Length, 13)) + "000";
                    }

                    versionList.TryGetValue(titleID.ToUpper(), out uint version);
                    versionList[titleID.ToUpper()] = Math.Max(version, title.version);
                }

                log?.WriteLine("Found {0} titles, last modified at {1}", versionList.Count, versionlist.last_modified);
            }
            catch { }

            log?.WriteLine("Initialization success");

            return(true);
        }
Exemplo n.º 7
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();
        }
Exemplo n.º 8
0
        private void OnNandFound()
        {
            Nand   nand       = NANDService.NAND;
            Stream NANDSource = NANDService.NANDSource;

            NANDSource.Seek(0x804000, SeekOrigin.Begin); // BCPKG2-1-Normal-Main offset + length of BootConfig
            FileStream pkg2stream = HACGUIKeyset.TempPkg2FileInfo.Create();

            NANDSource.CopyToNew(pkg2stream, 0x7FC000); // rest of BCPPKG2-Normal-Main partition
            pkg2stream.Seek(0, SeekOrigin.Begin);
            byte[] pkg2raw = new byte[pkg2stream.Length];
            pkg2stream.Read(pkg2raw, 0, pkg2raw.Length);

            Package2 pkg2 = new Package2(HACGUIKeyset.Keyset, new MemoryStream(pkg2raw));

            HACGUIKeyset.RootTempPkg2FolderInfo.Create();
            FileStream kernelstream = HACGUIKeyset.TempKernelFileInfo.Create();
            FileStream INI1stream   = HACGUIKeyset.TempINI1FileInfo.Create();

            pkg2.OpenKernel().CopyTo(kernelstream);
            pkg2.OpenIni1().CopyTo(INI1stream);
            kernelstream.Close();
            INI1stream.Close();

            Ini1 INI1 = new Ini1(pkg2.OpenIni1());
            List <HashSearchEntry>      hashes = new List <HashSearchEntry>();
            Dictionary <byte[], byte[]> keys   = new Dictionary <byte[], byte[]>();

            HACGUIKeyset.RootTempINI1Folder.Create();
            foreach (Kip kip in INI1.Kips)
            {
                Stream rodatastream, datastream;
                switch (kip.Header.Name)
                {
                case "FS":
                    hashes.Add(new HashSearchEntry(NintendoKeys.KeyAreaKeyApplicationSourceHash, 0x10));
                    hashes.Add(new HashSearchEntry(NintendoKeys.KeyAreaKeyOceanSourceHash, 0x10));
                    hashes.Add(new HashSearchEntry(NintendoKeys.KeyAreaKeySystemSourceHash, 0x10));
                    hashes.Add(new HashSearchEntry(NintendoKeys.HeaderKekSourceHash, 0x10));
                    hashes.Add(new HashSearchEntry(NintendoKeys.SaveMacKekSourceHash, 0x10));
                    hashes.Add(new HashSearchEntry(NintendoKeys.SaveMacKeySourceHash, 0x10));

                    rodatastream = new MemoryStream(kip.DecompressSection(1));
                    keys         = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x10);
                    Array.Copy(keys[NintendoKeys.KeyAreaKeyApplicationSourceHash], HACGUIKeyset.Keyset.KeyAreaKeyApplicationSource, 0x10);
                    Array.Copy(keys[NintendoKeys.KeyAreaKeyOceanSourceHash], HACGUIKeyset.Keyset.KeyAreaKeyOceanSource, 0x10);
                    Array.Copy(keys[NintendoKeys.KeyAreaKeySystemSourceHash], HACGUIKeyset.Keyset.KeyAreaKeySystemSource, 0x10);
                    Array.Copy(keys[NintendoKeys.HeaderKekSourceHash], HACGUIKeyset.Keyset.HeaderKekSource, 0x10);
                    Array.Copy(keys[NintendoKeys.SaveMacKekSourceHash], HACGUIKeyset.Keyset.SaveMacKekSource, 0x10);
                    Array.Copy(keys[NintendoKeys.SaveMacKeySourceHash], HACGUIKeyset.Keyset.SaveMacKeySource, 0x10);

                    hashes.Clear();
                    rodatastream.Seek(0, SeekOrigin.Begin);

                    bool sdWarn = false;

                    hashes.Add(new HashSearchEntry(NintendoKeys.SDCardKekSourceHash, 0x10));
                    try
                    {
                        keys = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x10);
                        Array.Copy(keys[NintendoKeys.SDCardKekSourceHash], HACGUIKeyset.Keyset.SdCardKekSource, 0x10);
                    }
                    catch (EndOfStreamException)
                    {
                        MessageBox.Show("Failed to find SD card kek source! The NAND is probably from 1.0.0.");
                        sdWarn = true;
                    }

                    if (!sdWarn)     // don't try to find the rest of the keys if the other one couldn't be found
                    {
                        hashes.Clear();
                        rodatastream.Seek(0, SeekOrigin.Begin);
                        hashes.Add(new HashSearchEntry(NintendoKeys.SDCardSaveKeySourceHash, 0x20));
                        hashes.Add(new HashSearchEntry(NintendoKeys.SDCardNcaKeySourceHash, 0x20));
                        keys = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x20);
                        Array.Copy(keys[NintendoKeys.SDCardSaveKeySourceHash], HACGUIKeyset.Keyset.SdCardKeySources[0], 0x20);
                        Array.Copy(keys[NintendoKeys.SDCardNcaKeySourceHash], HACGUIKeyset.Keyset.SdCardKeySources[1], 0x20);
                    }

                    hashes.Clear();
                    rodatastream.Close();

                    hashes.Add(new HashSearchEntry(NintendoKeys.HeaderKeySourceHash, 0x20));
                    datastream = new MemoryStream(kip.DecompressSection(2));
                    keys       = datastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x20);
                    Array.Copy(keys[NintendoKeys.HeaderKeySourceHash], HACGUIKeyset.Keyset.HeaderKeySource, 0x20);

                    datastream.Close();
                    hashes.Clear();

                    break;

                case "spl":
                    hashes.Add(new HashSearchEntry(NintendoKeys.AesKeyGenerationSourceHash, 0x10));

                    rodatastream = new MemoryStream(kip.DecompressSection(1));
                    keys         = rodatastream.FindKeyViaHash(hashes, new SHA256Managed(), 0x10);
                    Array.Copy(keys[NintendoKeys.AesKeyGenerationSourceHash], HACGUIKeyset.Keyset.AesKeyGenerationSource, 0x10);

                    rodatastream.Close();
                    hashes.Clear();
                    break;
                }

                FileStream kipstream = HACGUIKeyset.RootTempINI1Folder.GetFile(kip.Header.Name + ".kip").Create();
                kip.OpenRawFile().CopyTo(kipstream);
                kipstream.Close();
            }

            pkg2stream.Close();
            INI1stream.Close();

            HACGUIKeyset.Keyset.DeriveKeys();

            SwitchFs fs = new SwitchFs(HACGUIKeyset.Keyset, NANDService.NAND.OpenSystemPartition());

            foreach (KeyValuePair <string, Nca> kv in fs.Ncas)
            {
                Nca nca = kv.Value;

                switch (nca.Header.TitleId)
                {
                case 0x0100000000000033:     // es
                    switch (nca.Header.ContentType)
                    {
                    case ContentType.Program:
                        NcaSection exefsSection = nca.Sections.FirstOrDefault(x => x?.Type == SectionType.Pfs0);
                        Stream     pfsStream    = nca.OpenSection(exefsSection.SectionNum, false, false);
                        Pfs        pfs          = new Pfs(pfsStream);
                        Nso        nso          = new Nso(pfs.OpenFile("main"));
                        NsoSection section      = nso.Sections[1];
                        Stream     data         = new MemoryStream(section.DecompressSection());
                        hashes.Clear();

                        hashes.Add(new HashSearchEntry(NintendoKeys.EticketRsaKekSourceHash, 0x10));
                        hashes.Add(new HashSearchEntry(NintendoKeys.EticketRsaKekekSourceHash, 0x10));
                        keys = data.FindKeyViaHash(hashes, new SHA256Managed(), 0x10, data.Length);
                        byte[] EticketRsaKekSource   = new byte[0x10];
                        byte[] EticketRsaKekekSource = new byte[0x10];
                        Array.Copy(keys[NintendoKeys.EticketRsaKekSourceHash], EticketRsaKekSource, 0x10);
                        Array.Copy(keys[NintendoKeys.EticketRsaKekekSourceHash], EticketRsaKekekSource, 0x10);

                        byte[] RsaOaepKekGenerationSource;
                        XOR(NintendoKeys.KekMasks[0], NintendoKeys.KekSeeds[3], out RsaOaepKekGenerationSource);

                        byte[] key1 = new byte[0x10];
                        Crypto.DecryptEcb(HACGUIKeyset.Keyset.MasterKeys[0], RsaOaepKekGenerationSource, key1, 0x10);
                        byte[] key2 = new byte[0x10];
                        Crypto.DecryptEcb(key1, EticketRsaKekekSource, key2, 0x10);
                        byte[] key3 = new byte[0x10];
                        Crypto.DecryptEcb(key2, EticketRsaKekSource, HACGUIKeyset.Keyset.EticketRsaKek, 0x10);
                        break;
                    }
                    break;
                }
            }

            Stream prodinfo     = nand.OpenProdInfo();
            Stream prodinfoFile = HACGUIKeyset.TempPRODINFOFileInfo.Create();

            prodinfo.CopyTo(prodinfoFile);
            prodinfo.Close();
            prodinfoFile.Seek(0, SeekOrigin.Begin);
            Calibration cal0 = new Calibration(prodinfoFile);

            HACGUIKeyset.Keyset.EticketExtKeyRsa = Crypto.DecryptRsaKey(cal0.EticketExtKeyRsa, HACGUIKeyset.Keyset.EticketRsaKek);
            prodinfoFile.Close();

            List <Ticket> tickets = new List <Ticket>();
            NandPartition system  = nand.OpenSystemPartition();

            Stream e1Stream = system.OpenFile("save\\80000000000000E1", FileMode.Open, FileAccess.Read);

            tickets.AddRange(ReadTickets(HACGUIKeyset.Keyset, e1Stream));

            Stream e2Stream = system.OpenFile("save\\80000000000000E2", FileMode.Open, FileAccess.Read);

            tickets.AddRange(ReadTickets(HACGUIKeyset.Keyset, e2Stream));

            Stream   nsAppmanStream = system.OpenFile("save\\8000000000000043", FileMode.Open, FileAccess.Read);
            Savefile save           = new Savefile(HACGUIKeyset.Keyset, nsAppmanStream, false);
            Stream   privateStream  = save.OpenFile("/private");

            byte[] sdSeed = new byte[0x10];
            privateStream.Read(sdSeed, 0, 0x10); // Seek doesn't work so i just read twice
            privateStream.Read(sdSeed, 0, 0x10);
            HACGUIKeyset.Keyset.SetSdSeed(sdSeed);

            foreach (Ticket ticket in tickets)
            {
                HACGUIKeyset.Keyset.TitleKeys[ticket.RightsId] = new byte[0x10];
                Array.Copy(ticket.TitleKeyBlock, HACGUIKeyset.Keyset.TitleKeys[ticket.RightsId], 0x10);
            }
            NANDService.Stop();

            HACGUIKeyset.ProductionKeysFileInfo.Create().WriteString(HACGUIKeyset.PrintCommonKeys(HACGUIKeyset.Keyset, true));
            HACGUIKeyset.ExtraKeysFileInfo.Create().WriteString(HACGUIKeyset.PrintCommonWithoutFriendlyKeys(HACGUIKeyset.Keyset));
            HACGUIKeyset.ConsoleKeysFileInfo.Create().WriteString(ExternalKeys.PrintUniqueKeys(HACGUIKeyset.Keyset));
            HACGUIKeyset.GetConsoleKeysFileInfoByName(PickConsole.ConsoleName).Create().WriteString(ExternalKeys.PrintUniqueKeys(HACGUIKeyset.Keyset));
            HACGUIKeyset.TitleKeysFileInfo.Create().WriteString(ExternalKeys.PrintTitleKeys(HACGUIKeyset.Keyset));
        }
Exemplo n.º 9
0
 private static void ProcessKeygen(Context ctx)
 {
     Console.WriteLine(ExternalKeys.PrintCommonKeys(ctx.Keyset));
 }
Exemplo n.º 10
0
        public MainPage()
        {
            InitializeComponent();
            Loaded += (_, __) =>
            {
                void rcmRefresh(bool b)
                {
                    foreach (MenuItem item in
                             RCMContextMenu.Items.Cast <MenuItem>().Where(i => i.Tag as string == "RequiresRCM"))
                    {
                        item.IsEnabled = b;
                    }
                };
                rcmRefresh(InjectService.LibusbKInstalled);

                void nandRefresh(bool b)
                {
                    foreach (MenuItem item in
                             NANDContextMenu.Items.Cast <MenuItem>().Where(i => i.Tag as string == "RequiresNAND"))
                    {
                        item.IsEnabled = b;
                    }
                };
                nandRefresh(false);

                InjectService.DeviceInserted += () =>
                {
                    if (InjectService.LibusbKInstalled)
                    {
                        Dispatcher.Invoke(() => rcmRefresh(true));
                    }
                };

                InjectService.DeviceRemoved += () =>
                {
                    Dispatcher.Invoke(() => rcmRefresh(false));
                };

                NANDService.OnNANDPluggedIn += () =>
                {
                    Dispatcher.Invoke(() => nandRefresh(true));
                };

                NANDService.OnNANDRemoved += () =>
                {
                    Dispatcher.Invoke(() => nandRefresh(false));
                };

                SDService.OnSDPluggedIn += (drive) =>
                {
                    DirectoryInfo root      = drive.RootDirectory;
                    DirectoryInfo switchDir = root.GetDirectory("switch");
                    if (switchDir.Exists)
                    {
                        FileInfo prodKeysInfo = switchDir.GetFile("prod.keys");
                        if (prodKeysInfo.Exists)
                        {
                            try
                            {
                                ExternalKeys.ReadKeyFile(HACGUIKeyset.Keyset, prodKeysInfo.FullName);
                                new SaveKeysetTask(null).CreateTask().RunSynchronously();
                            }
                            catch (Exception e)
                            {
                                MessageBox.Show($"An error occured when attempting to import keys from SD card. It could be corrupted.\nError: {e.Message}");
                            }
                        }
                    }
                };

                // init this first as other pages may request tasks on init
                TaskManagerView          = new TaskManagerPage();
                TaskManagerFrame.Content = TaskManagerView;

                StatusService.Bar = StatusBar;
                StatusService.CurrentTaskBlock = CurrentTaskBlock;
                CurrentTaskBlock.Background    = StatusBar.Background;
                TaskManagerView.Queue.Submit(new RunTask("Opening/Deriving keys...", new Task(() => HACGUIKeyset.Keyset.LoadAll())));

                DeviceService.Start();

                TitleManagerView          = new MainTitleManagerPage();
                TitleManagerFrame.Content = TitleManagerView;
                SaveManagerView           = new SaveManagerPage(0);
                SaveManagerFrame.Content  = SaveManagerView;

                StatusService.Start();

                if (Native.IsAdministrator)
                {
                    AdminButton.IsEnabled = false;
                }
            };
        }
Exemplo n.º 11
0
        private static void Main(string[] args)
        {
            var keyFile       = Environment.ExpandEnvironmentVariables("%USERPROFILE%/.switch/prod.keys");
            var keysInUserDir = true;

            var getDeltasOnly = false;

            #region Pre-execution checks
            if (!File.Exists(keyFile))
            {
                if (!File.Exists("prod.keys"))
                {
                    Console.Error.WriteLine("Error: prod.keys is missing!");
                    return;
                }
                else
                {
                    keysInUserDir = false;
                }
            }

            if (!File.Exists("edge.token"))
            {
                Console.Error.WriteLine("Error: Please add an edge token to a file named \"edge.token\".");
                return;
            }

            if (!File.Exists("device.id"))
            {
                Console.Error.WriteLine("Error: Please add your device ID in hexadecimal text form to a file named \"device.id\".");
                return;
            }

            if (!File.Exists("nx_tls_client_cert.pfx"))
            {
                Console.Error.WriteLine("Error: Please add your Switch certificate to a file named \"nx_tls_client_cert.pfx\".");
                return;
            }
            #endregion

            var deviceID = Convert.ToInt64(File.ReadAllText("device.id"), 16);
            var keys     = ExternalKeys.ReadKeyFile(keysInUserDir ? keyFile : "prod.keys");

            var sysID = "0100000000000816";

            // To-do: Clean up
            if (args[0] == "-s" || args[0] == sysID)
            {
                var JSON    = (string)GET(deviceID, SunUrl, true);
                var Version = args.Length > 1 ? args[1] : (string)JObject.Parse(JSON)["system_update_metas"][0]["title_version"];
                HEAD(deviceID, nMetaURL('s', sysID, Version, deviceID));
                var contentID = HEAD(deviceID, nMetaURL('s', sysID, Version, deviceID));

                using (var meta = (HttpWebResponse)GET(deviceID, nContentURL('s', contentID), false))
                    using (var rd = new BinaryReader(meta.GetResponseStream()))
                        using (var strm = new MemoryStorage(rd.ReadBytes((int)meta.ContentLength)))
                        {
                            Directory.CreateDirectory(sysID);
                            strm.WriteAllBytes($"{sysID}/{contentID}.cnmt.nca");
                            using (var nca = new Nca(keys, strm, false).OpenSection(0, false, IntegrityCheckLevel.None, false))
                            {
                                var pfs  = new Pfs(nca);
                                var cnmt = new Cnmt(pfs.OpenFile(pfs.Files[0]).AsStream());
                                foreach (var entry in cnmt.MetaEntries)
                                {
                                    var tid = $"{entry.TitleId:x16}";
                                    HEAD(deviceID, nMetaURL('a', tid, $"{entry.Version.Version}", deviceID));
                                    var cID = HEAD(deviceID, nMetaURL('a', tid, $"{entry.Version.Version}", deviceID));

                                    using (var met2 = (HttpWebResponse)GET(deviceID, nContentURL('a', cID), false))
                                        using (var rdr = new BinaryReader(met2.GetResponseStream()))
                                            using (var strm2 = new MemoryStorage(rdr.ReadBytes((int)meta.ContentLength)))
                                            {
                                                Directory.CreateDirectory($"{sysID}/{tid}");
                                                strm2.WriteAllBytes($"{sysID}/{tid}/{cID}.cnmt.nca");
                                                using (var nca2 = new Nca(keys, strm2, false).OpenSection(0, false, IntegrityCheckLevel.None, false))
                                                {
                                                    var pfs2  = new Pfs(nca2);
                                                    var cnmt2 = new Cnmt(pfs2.OpenFile(pfs2.Files[0]).AsStream());
                                                    foreach (var entry2 in cnmt2.ContentEntries)
                                                    {
                                                        string NCAID = entry2.NcaId.ToHexString().ToLower();
                                                        using (var Req = (HttpWebResponse)GET(deviceID, nContentURL('c', NCAID), false))
                                                            using (var Output = File.OpenWrite($"{sysID}/{tid}/{NCAID}.nca"))
                                                                Req.GetResponseStream().CopyTo(Output);
                                                    }
                                                }
                                            }
                                }
                            }
                        }

                return;
            }

            string id          = null,
                   idFirstReq  = null,
                   idSecondReq = null;

            List <string> tidTargets   = new List <string>(),
                          verTargets   = new List <string>(),
                          entryTargets = new List <string>();

            var numOfListings = 0;

            if (args.Length == 2)
            {
                if (args[1] == "-d")
                {
                    getDeltasOnly = true;
                }
                else if (args[0] == "-t")
                {
                    var rightsID = args[1];
                    using (var tikReq = (HttpWebResponse)GET(deviceID, CETKURL(rightsID), false))
                        using (var strm = tikReq.GetResponseStream())
                            using (var rd = new BinaryReader(strm))
                            {
                                File.WriteAllBytes($"{rightsID}.tik", rd.ReadBytes(0x2C0));
                                File.WriteAllBytes($"{rightsID}.cert", rd.ReadBytes(0x700));
                            }

                    return;
                }
            }

            GET(deviceID, Aqua(deviceID), false);

            if (args.Length == 3)
            {
                numOfListings = 2;
                if (args[0].Substring(13, 3) != "000" && args[0].Substring(13, 3) != "800")
                {
                    tidTargets.Add(null);
                    tidTargets.Add(args[0]);
                }
                else
                {
                    tidTargets.Add(null);
                    tidTargets.Add($"{args[0].Substring(0, 13)}800");
                }
                verTargets.Add(null);
                verTargets.Add(args[2]);
            }
            else
            {
                var Streq = (string)GET(deviceID, Superfly(GetBaseTID(args[0])), true);
                if (args[0].Substring(13, 3) == "000")
                {
                    foreach (JToken Listing in JArray.Parse(Streq))
                    {
                        if ((string)Listing["title_type"] != "AddOnContent")
                        {
                            numOfListings++;
                            tidTargets.Add(Listing["title_id"].ToString());
                            verTargets.Add(Listing["version"].ToString());
                        }
                    }
                }
                else
                {
                    foreach (JToken Listing in JArray.Parse(Streq))
                    {
                        if ((string)Listing["title_id"] == args[0])
                        {
                            numOfListings++;
                            tidTargets.Add(Listing["title_id"].ToString());
                            verTargets.Add(Listing["version"].ToString());
                        }
                    }
                }
            }

            if (args.Length == 1)
            {
                id = HEAD(deviceID, MetaURL('a', tidTargets[0], verTargets[0], deviceID));
            }

            if (args.Length == 1 && id != null)
            {
                GET(deviceID, ContentURL('a', id), true);
            }

            if (numOfListings >= 2)
            {
                idFirstReq = HEAD(deviceID, MetaURL('a', tidTargets[1], verTargets[1], deviceID));
            }

            if (args.Length == 1 && numOfListings >= 2)
            {
                GET(deviceID, ContentURL('a', idFirstReq), true);
            }

            if (numOfListings >= 2)
            {
                idSecondReq = HEAD(deviceID, MetaURL('a', tidTargets[1], verTargets[1], deviceID));
            }

            if (numOfListings >= 2)
            {
                GET(deviceID, ContentURL('a', idSecondReq), true);
            }

            if (args.Length == 1)
            {
                using (var meta = (HttpWebResponse)GET(deviceID, ContentURL('a', id), false))
                    using (var rd = new BinaryReader(meta.GetResponseStream()))
                        using (var strm = new MemoryStorage(rd.ReadBytes((int)meta.ContentLength)))
                        {
                            Directory.CreateDirectory(tidTargets[0]);
                            strm.WriteAllBytes($"{tidTargets[0]}/{id}.cnmt.nca");
                            using (var nca = new Nca(keys, strm, false).OpenSection(0, false, IntegrityCheckLevel.None, false))
                            {
                                var pfs  = new Pfs(nca);
                                var cnmt = new Cnmt(pfs.OpenFile(pfs.Files[0]).AsStream());
                                foreach (var entry in cnmt.ContentEntries)
                                {
                                    string NCAID = entry.NcaId.ToHexString().ToLower();
                                    using (var Req = (HttpWebResponse)GET(deviceID, ContentURL('c', NCAID), false))
                                        using (var Output = File.OpenWrite($"{tidTargets[0]}/{NCAID}.nca"))
                                            Req.GetResponseStream().CopyTo(Output);
                                }
                            }
                        }
            }

            if (numOfListings >= 2)
            {
                using (var meta = (HttpWebResponse)GET(deviceID, ContentURL('a', idSecondReq), false))
                    using (var read = new BinaryReader(meta.GetResponseStream()))
                        using (var metastrm = new MemoryStorage(read.ReadBytes((int)meta.ContentLength)))
                        {
                            Directory.CreateDirectory(tidTargets[1]);
                            metastrm.WriteAllBytes($"{tidTargets[1]}/{idSecondReq}.cnmt.nca");
                            using (var nca = new Nca(keys, metastrm, false).OpenSection(0, false, IntegrityCheckLevel.None, false))
                            {
                                var pfs  = new Pfs(nca);
                                var cnmt = new Cnmt(pfs.OpenFile(pfs.Files[0]).AsStream());
                                foreach (var entry in getDeltasOnly ?
                                         cnmt.ContentEntries.Where(e => e.Type == CnmtContentType.DeltaFragment) :
                                         cnmt.ContentEntries)
                                {
                                    var ncaID = entry.NcaId.ToHexString().ToLower();
                                    using (var request = (HttpWebResponse)GET(deviceID, ContentURL('c', ncaID), false))
                                        using (var output = File.OpenWrite($"{tidTargets[1]}/{ncaID}.nca"))
                                            request.GetResponseStream().CopyTo(output);

                                    if (entry.Type == CnmtContentType.Program)
                                    {
                                        var rightsID = new Nca(keys, new StreamStorage
                                                                   (File.OpenRead($"{tidTargets[1]}/{ncaID}.nca"), false), false)
                                                       .Header.RightsId.ToHexString().ToLower();

                                        using (var tikReq = (HttpWebResponse)GET(deviceID, CETKURL(rightsID), false))
                                            using (var strm = tikReq.GetResponseStream())
                                                using (var rd = new BinaryReader(strm))
                                                {
                                                    File.WriteAllBytes($"{tidTargets[1]}/{rightsID}.tik", rd.ReadBytes(0x2C0));
                                                    File.WriteAllBytes($"{tidTargets[1]}/{rightsID}.cert", rd.ReadBytes(0x700));
                                                }
                                    }
                                }
                            }
                        }
            }
        }
Exemplo n.º 12
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)
                {
                    return(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);

                    Input = Pfs.OpenFile
                            (
                        Pfs.Files.OrderByDescending(s => s.Size)
                        .FirstOrDefault()
                            );
                }
                else if (Ext == ".xci")
                {
                    var InputPFS = File.OpenRead(FileToOpen);
                    var Xci      = new Xci(Keys, InputPFS);

                    Input = Xci.SecurePartition.OpenFile
                            (
                        Xci.SecurePartition.Files
                        .OrderByDescending(s => s.Size)
                        .FirstOrDefault()
                            );
                }
                else
                {
                    Input = File.OpenRead(FileToOpen);
                }

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

                    if (Nca.HasRightsId)
                    {
                        if (!Keys.TitleKeys.Keys.Contains(Nca.Header.RightsId))
                        {
                            MessageBox.Show($"Error: the titlekey for {Nca.Header.RightsId.ToHexString()} is not present in your key file.");
                        }
                    }

                    bool IsUpdateNca = false;

                    foreach (var Section in Nca.Sections)
                    {
                        if (Section?.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.Invoke
                        (
                            new Action
                            (
                                () => { label3.Text = Info[1]; }
                            )
                        );
                    }
                    )
                    .Start();

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

                    IO.PopulateTreeView(treeView1.Nodes, Rom.RootDir);
                }
                catch (Exception)
                {
                    MessageBox.Show("There was an error reading the NCA. Are you sure the correct keys are present in your keyfiles?");
                }
            }
            catch (Exception)
            {
                MessageBox.Show("Error: key files are missing!");
            }
        }
Exemplo n.º 13
0
        static void Main(string[] args)
        {
            var path = args.Length >= 1
                ? args[0]
                : Environment.CurrentDirectory;

            var fs = new FileSystem(path);

            if (!File.Exists("keys.txt"))
            {
                Console.WriteLine("Cannot verify NSPs without keys.txt");
                Console.WriteLine();
                Console.WriteLine("Press any key to continue");
                Console.ReadKey();
                return;
            }

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



            foreach (var file in fs.GetFileSystemEntries("", "*.nsp", SearchOption.AllDirectories))
            {
                var filename = Path.GetFileName(file);
                var progress = $"Checking {filename}: ";
                Console.Write(progress);
                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(filename);
                            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(filename);
                                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(filename);
                                    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(filename);
                                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($"{filename}{Environment.NewLine}Exception: {ex.Message}{Environment.NewLine}Stack Trace: {ex.StackTrace}{Environment.NewLine}");
                }
            }

            File.WriteAllText("Corrupted NSPs.txt", string.Join(Environment.NewLine, badlist));
            File.WriteAllText("Exception Log.txt", string.Join(Environment.NewLine, exceptionlist));

            Console.WriteLine();
            Console.WriteLine("Press any key to continue");
            Console.ReadKey();
        }
Exemplo n.º 14
0
 public void CopyKeyset()
 {
     ExternalKeys.ReadKeyFile(HACGUIKeyset.Keyset, KeysetFile.FullName);
     HACGUIKeyset.Keyset.DeriveKeys(); // derive from keyblobs
 }