コード例 #1
0
ファイル: StorageOnNcaCreator.cs プロジェクト: garoxas/LibHac
        // todo: Implement NcaReader and other Nca classes
        public Result Create(out ReferenceCountedDisposable <IStorage> storage, out NcaFsHeader fsHeader, Nca nca,
                             int fsIndex, bool isCodeFs)
        {
            UnsafeHelpers.SkipParamInit(out storage, out fsHeader);

            Result rc = OpenStorage(out IStorage storageTemp, nca, fsIndex);

            if (rc.IsFailure())
            {
                return(rc);
            }

            if (isCodeFs)
            {
                using (var codeFs = new PartitionFileSystemCore <StandardEntry>())
                {
                    rc = codeFs.Initialize(storageTemp);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    rc = VerifyAcidSignature(codeFs, nca);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }
            }

            storage  = new ReferenceCountedDisposable <IStorage>(storageTemp);
            fsHeader = nca.GetFsHeader(fsIndex);

            return(Result.Success);
        }
コード例 #2
0
        public ExtractPartition(List <SwitchFsNca> selected) : base(selected)
        {
            InitializeComponent();

            Indexed = new Dictionary <NcaFormatType, List <Tuple <SwitchFsNca, int> > >();
            foreach (SwitchFsNca nca in selected)
            {
                if (nca.Nca.Header.ContentType != ContentType.Meta)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        if (!nca.Nca.Header.IsSectionEnabled(i))
                        {
                            continue;
                        }
                        NcaFsHeader section = nca.Nca.Header.GetFsHeader(i);
                        if (!Indexed.ContainsKey(section.FormatType))
                        {
                            Indexed[section.FormatType] = new List <Tuple <SwitchFsNca, int> >();
                        }
                        Indexed[section.FormatType].Add(new Tuple <SwitchFsNca, int>(nca, i));
                    }
                }
            }

            if (Indexed.ContainsKey(NcaFormatType.Romfs))
            {
                ComboBox.Items.Add(MountType.Romfs);
            }
            if (Indexed.ContainsKey(NcaFormatType.Pfs0))
            {
                ComboBox.Items.Add(MountType.Exefs);
            }
        }
コード例 #3
0
        public TitleMountDialog(Dictionary <NcaFormatType, List <Tuple <SwitchFsNca, int> > > indexed, SwitchFsNca mainNca)
        {
            InitializeComponent();
            Indexed = indexed;
            MainNca = mainNca;

            bool hasPatch = false;

            foreach (Tuple <SwitchFsNca, int> t in Indexed.Values.SelectMany(i => i))
            {
                NcaFsHeader section = t.Item1.Nca.Header.GetFsHeader(t.Item2);
                if (section.IsPatchSection())
                {
                    hasPatch = true;
                    break;
                }
            }

            if (Indexed.ContainsKey(NcaFormatType.Romfs) || hasPatch)
            {
                ComboBox.Items.Add(MountType.Romfs);
            }
            if (Indexed.ContainsKey(NcaFormatType.Pfs0))
            {
                ComboBox.Items.Add(MountType.Exefs);
            }
        }
コード例 #4
0
        // todo: Implement NcaReader and other Nca classes
        public Result Create(out IStorage storage, out NcaFsHeader fsHeader, Nca nca, int fsIndex, bool isCodeFs)
        {
            storage  = default;
            fsHeader = default;

            Result rc = OpenStorage(out IStorage storageTemp, nca, fsIndex);

            if (rc.IsFailure())
            {
                return(rc);
            }

            if (isCodeFs)
            {
                using (var codeFs = new PartitionFileSystemCore <StandardEntry>())
                {
                    rc = codeFs.Initialize(storageTemp);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }

                    rc = VerifyAcidSignature(codeFs, nca);
                    if (rc.IsFailure())
                    {
                        return(rc);
                    }
                }
            }

            storage  = storageTemp;
            fsHeader = nca.GetFsHeader(fsIndex);

            return(Result.Success);
        }
コード例 #5
0
        private void MountClicked(object sender, RoutedEventArgs e)
        {
            if (ComboBox.SelectedItem == null)
            {
                return;
            }

            MountType     mountType   = (MountType)ComboBox.SelectedItem;
            NcaFormatType sectionType = NcaFormatType.Romfs;

            switch (mountType)
            {
            case MountType.Exefs:
                sectionType = NcaFormatType.Pfs0;
                break;

            case MountType.Romfs:
                sectionType = NcaFormatType.Romfs;
                break;
            }
            List <IFileSystem> filesystems = new List <IFileSystem>();
            IEnumerable <Tuple <SwitchFsNca, int> > list = Indexed[sectionType];

            TaskManagerPage.Current.Queue.Submit(new RunTask("Opening filesystems to mount...", new Task(() =>
            {
                foreach (Tuple <SwitchFsNca, int> t in list)
                {
                    SwitchFsNca nca     = t.Item1;
                    NcaFsHeader section = t.Item1.Nca.Header.GetFsHeader(t.Item2);
                    int index           = t.Item2;

                    /*IStorage inStorage = nca.OpenStorage(index, IntegrityCheckLevel.ErrorOnInvalid);
                     * IFile outFile = new LocalFile("./tmp.bin", OpenMode.Write | OpenMode.AllowAppend);
                     * IStorage outStorage = outFile.AsStorage();
                     * inStorage.GetSize(out long size);
                     * long buffLen = 0x10000;
                     * for (int i = 0; i < (int)Math.Min(Math.Ceiling((double)size / buffLen), 5); i++)
                     * {
                     *  long off = i * buffLen;
                     *  long left = size - off;
                     *  long toRead = Math.Min(buffLen, left);
                     *
                     *  byte[] buff = new byte[toRead];
                     *
                     *  inStorage.Read(off, buff);
                     *  outStorage.Write(off, buff);
                     * }
                     * //inStorage.Dispose();
                     * outFile.Dispose();*/

                    filesystems.Add(nca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid));
                }
                filesystems.Reverse();
                LayeredFileSystem fs = new LayeredFileSystem(filesystems);
                string typeString    = sectionType.ToString();
                MountService.Mount(new MountableFileSystem(fs, $"Mounted {mountType.ToString().ToLower()}", typeString, OpenMode.Read));
            })));
        }
コード例 #6
0
        private void MountClicked(object sender, RoutedEventArgs e)
        {
            List <Title> selected = new List <Title>();

            foreach (TitleElement info in ListView.Items)
            {
                if (info.Selected)
                {
                    selected.Add(info.Title);
                }
            }

            List <Title> orderedTitles = Element.OrderTitlesByBest();

            Title baseTitle = orderedTitles.FirstOrDefault(t => t.Metadata.Type == TitleType.Application);

            if (baseTitle == null && orderedTitles.Count == 1)
            {
                baseTitle = orderedTitles.First();
            }

            if (!IsMountable(baseTitle, selected))
            {
                MessageBox.Show("The base game isn't available, so the patch cannot be mounted.");
                return;
            }

            Dictionary <NcaFormatType, List <Tuple <SwitchFsNca, int> > > indexed = new Dictionary <NcaFormatType, List <Tuple <SwitchFsNca, int> > >();

            foreach (Title title in selected)
            {
                SwitchFsNca nca = title.MainNca;
                if (nca.Nca.Header.ContentType != ContentType.Meta)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        if (!nca.Nca.Header.IsSectionEnabled(i))
                        {
                            continue;
                        }
                        NcaFsHeader section = nca.Nca.Header.GetFsHeader(i);
                        if (!indexed.ContainsKey(section.FormatType))
                        {
                            indexed[section.FormatType] = new List <Tuple <SwitchFsNca, int> >();
                        }
                        indexed[section.FormatType].Add(new Tuple <SwitchFsNca, int>(nca, i));
                    }
                }
            }
            Window window = new TitleMountDialog(indexed, baseTitle.MainNca)
            {
                Owner = Window.GetWindow(this)
            };

            window.ShowDialog();
        }
コード例 #7
0
        private void ExtractClicked(object sender, RoutedEventArgs e)
        {
            MountType     mountType   = (MountType)ComboBox.SelectedItem;
            NcaFormatType sectionType = NcaFormatType.Romfs;

            switch (mountType)
            {
            case MountType.Exefs:
                sectionType = NcaFormatType.Pfs0;
                break;

            case MountType.Romfs:
                sectionType = NcaFormatType.Romfs;
                break;
            }

            IEnumerable <Tuple <SwitchFsNca, int> > list = Indexed[sectionType];
            string path = Path.Text;

            TaskManagerPage.Current.Queue.Submit(new RunTask("Opening filesystems to extract...", new Task(() =>
            {
                List <IFileSystem> filesystems = new List <IFileSystem>();
                foreach (Tuple <SwitchFsNca, int> t in list)
                {
                    SwitchFsNca nca     = t.Item1;
                    NcaFsHeader section = t.Item1.Nca.Header.GetFsHeader(t.Item2);
                    int index           = t.Item2;

                    filesystems.Add(nca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid));
                }
                filesystems.Reverse();

                LayeredFileSystem lfs      = new LayeredFileSystem(filesystems);
                ExtractFileSystemTask task = new ExtractFileSystemTask($"Extracting {sectionType}...", lfs, path);

                Dispatcher.InvokeAsync(() =>
                {
                    ProgressView view = new ProgressView(new List <ProgressTask>()
                    {
                        task
                    });
                    NavigationWindow window = new NavigationWindow
                    {
                        ShowsNavigationUI = false // get rid of the t r a s h
                    };
                    window.Navigate(view);

                    TaskManagerPage.Current.Queue.Submit(task);

                    window.Owner = Window.GetWindow(this);
                    window.ShowDialog();
                });
            })));
        }
コード例 #8
0
ファイル: Extensions.cs プロジェクト: SIMOMEGA/HACGUI
 public static NcaFsHeader GetFsHeader(this NcaHeader obj, NcaFormatType type)
 {
     for (int i = 0; i < 4; i++)
     {
         NcaFsHeader header = obj.GetFsHeader(i);
         if (header.FormatType == type)
         {
             return(header);
         }
     }
     throw new InvalidOperationException($"NCA is missing section type {type}");
 }
コード例 #9
0
            void PrintSha256Hash(NcaFsHeader sect, int index)
            {
                NcaFsIntegrityInfoSha256 hashInfo = sect.GetIntegrityInfoSha256();

                PrintItem(sb, colLen, $"        Master Hash{nca.ValidateSectionMasterHash(index).GetValidityString()}:", hashInfo.MasterHash.ToArray());
                sb.AppendLine("        Hash Table:");

                PrintItem(sb, colLen, "            Offset:", $"0x{hashInfo.GetLevelOffset(0):x12}");
                PrintItem(sb, colLen, "            Size:", $"0x{hashInfo.GetLevelSize(0):x12}");
                PrintItem(sb, colLen, "            Block Size:", $"0x{hashInfo.BlockSize:x}");
                PrintItem(sb, colLen, "        PFS0 Offset:", $"0x{hashInfo.GetLevelOffset(1):x12}");
                PrintItem(sb, colLen, "        PFS0 Size:", $"0x{hashInfo.GetLevelSize(1):x12}");
            }
コード例 #10
0
            static string GetPartitionType(NcaFsHeader fsHeader, bool isExefs, bool isNca0)
            {
                if (isExefs)
                {
                    return("ExeFS");
                }
                if (isNca0 && fsHeader.FormatType == NcaFormatType.Romfs)
                {
                    return("NCA0 RomFS");
                }

                return(fsHeader.FormatType.Print() + (fsHeader.IsPatchSection() ? " patch" : ""));
            }
コード例 #11
0
ファイル: Extensions.cs プロジェクト: SIMOMEGA/HACGUI
        public static void MatchupBaseNca(this IEnumerable <SwitchFsNca> ncas)
        {
            PseudoFileSystem ps = ncas.MakeFs();
            SwitchFs         fs = SwitchFs.OpenNcaDirectory(HACGUIKeyset.Keyset, ps);

            foreach (KeyValuePair <ulong, LibHac.Application> kv in fs.Applications)
            {
                ulong tid = kv.Key;
                LibHac.Application app = kv.Value;

                if (app.Patch != null && app.Main != null)
                {
                    foreach (SwitchFsNca nca in app.Patch.Ncas)
                    {
                        ContentType type    = nca.Nca.Header.ContentType;
                        SwitchFsNca baseNca = app.Main.Ncas.Where(n => n.Nca.Header.ContentType == type).FirstOrDefault();
                        if (baseNca != null)
                        {
                            bool hasPatch = false;
                            for (int i = 0; i < 4; i++)
                            {
                                Nca n = nca.Nca;
                                if (n.CanOpenSection(i))
                                {
                                    NcaFsHeader section = n.Header.GetFsHeader(i);
                                    if (section.IsPatchSection())
                                    {
                                        hasPatch = true;
                                        break;
                                    }
                                }
                            }
                            if (hasPatch)
                            {
                                ncas.Where(n => n.Filename == nca.Filename.Replace("/", "")).First().BaseNca = baseNca.Nca; // set original NCA, not new parsed one
                            }
                        }
                    }
                }
            }
        }
コード例 #12
0
        private void MountClicked(object sender, RoutedEventArgs e)
        {
            List <SwitchFsNca> selected = new List <SwitchFsNca>();

            foreach (NcaElement info in ListView.Items)
            {
                if (info.Selected)
                {
                    selected.Add(info.Nca);
                }
            }


            Dictionary <NcaFormatType, List <Tuple <SwitchFsNca, int> > > indexed = new Dictionary <NcaFormatType, List <Tuple <SwitchFsNca, int> > >();

            foreach (SwitchFsNca nca in selected)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (!nca.Nca.Header.IsSectionEnabled(i))
                    {
                        continue;
                    }
                    NcaFsHeader section = nca.Nca.Header.GetFsHeader(i);
                    if (!indexed.ContainsKey(section.FormatType))
                    {
                        indexed[section.FormatType] = new List <Tuple <SwitchFsNca, int> >();
                    }
                    indexed[section.FormatType].Add(new Tuple <SwitchFsNca, int>(nca, i));
                }
            }

            Window window = new TitleMountDialog(indexed)
            {
                Owner = Window.GetWindow(this)
            };

            window.ShowDialog();
        }
コード例 #13
0
        private void MountClicked(object sender, RoutedEventArgs e)
        {
            MountType     mountType   = (MountType)ComboBox.SelectedItem;
            NcaFormatType sectionType = NcaFormatType.Romfs;

            switch (mountType)
            {
            case MountType.Exefs:
                sectionType = NcaFormatType.Pfs0;
                break;

            case MountType.Romfs:
                sectionType = NcaFormatType.Romfs;
                break;
            }
            List <IFileSystem> filesystems = new List <IFileSystem>();
            IEnumerable <Tuple <SwitchFsNca, int> > list = Indexed[sectionType];

            TaskManagerPage.Current.Queue.Submit(new RunTask("Opening filesystems to mount...", new Task(() =>
            {
                foreach (Tuple <SwitchFsNca, int> t in list)
                {
                    SwitchFsNca nca     = t.Item1;
                    NcaFsHeader section = t.Item1.Nca.Header.GetFsHeader(t.Item2);
                    int index           = t.Item2;

                    if (section.IsPatchSection())
                    {
                        MainNca.BaseNca = nca.Nca;
                    }

                    filesystems.Add(nca.OpenFileSystem(index, IntegrityCheckLevel.ErrorOnInvalid));
                }
                filesystems.Reverse();
                LayeredFileSystem fs = new LayeredFileSystem(filesystems);
                string typeString    = sectionType.ToString();
                MountService.Mount(new MountableFileSystem(fs, $"Mounted {mountType.ToString().ToLower()}", typeString, OpenMode.Read));
            })));
        }
コード例 #14
0
 public Result CreateWithPatch(out IStorage storage, out NcaFsHeader fsHeader, Nca baseNca, Nca patchNca, int fsIndex, bool isCodeFs)
 {
     throw new NotImplementedException();
 }
コード例 #15
0
ファイル: StorageOnNcaCreator.cs プロジェクト: garoxas/LibHac
 public Result CreateWithPatch(out ReferenceCountedDisposable <IStorage> storage, out NcaFsHeader fsHeader,
                               Nca baseNca, Nca patchNca, int fsIndex, bool isCodeFs)
 {
     throw new NotImplementedException();
 }
コード例 #16
0
ファイル: ProcessNca.cs プロジェクト: leo60228/LibHac
        private static string Print(this NcaHolder ncaHolder)
        {
            Nca nca       = ncaHolder.Nca;
            int masterKey = Keyset.GetMasterKeyRevisionFromKeyGeneration(nca.Header.KeyGeneration);

            int colLen = 36;
            var sb     = new StringBuilder();

            sb.AppendLine();

            sb.AppendLine("NCA:");
            PrintItem(sb, colLen, "Magic:", MagicToString(nca.Header.Magic));
            PrintItem(sb, colLen, $"Fixed-Key Signature{nca.VerifyHeaderSignature().GetValidityString()}:", nca.Header.Signature1.ToArray());
            PrintItem(sb, colLen, $"NPDM Signature{nca.VerifySignature2().GetValidityString()}:", nca.Header.Signature2.ToArray());
            PrintItem(sb, colLen, "Content Size:", $"0x{nca.Header.NcaSize:x12}");
            PrintItem(sb, colLen, "TitleID:", $"{nca.Header.TitleId:X16}");
            if (nca.CanOpenSection(NcaSectionType.Code))
            {
                IFileSystem fs = nca.OpenFileSystem(NcaSectionType.Code, IntegrityCheckLevel.None);
                Result      r  = fs.OpenFile(out IFile file, "/main.npdm".ToU8String(), OpenMode.Read);
                if (r.IsSuccess())
                {
                    var npdm = new NpdmBinary(file.AsStream(), null);
                    PrintItem(sb, colLen, "Title Name:", npdm.TitleName);
                }
            }

            PrintItem(sb, colLen, "SDK Version:", nca.Header.SdkVersion);
            PrintItem(sb, colLen, "Distribution type:", nca.Header.DistributionType);
            PrintItem(sb, colLen, "Content Type:", nca.Header.ContentType);
            PrintItem(sb, colLen, "Master Key Revision:", $"{masterKey} ({Utilities.GetKeyRevisionSummary(masterKey)})");
            PrintItem(sb, colLen, "Encryption Type:", $"{(nca.Header.HasRightsId ? "Titlekey crypto" : "Standard crypto")}");

            if (nca.Header.HasRightsId)
            {
                PrintItem(sb, colLen, "Rights ID:", nca.Header.RightsId.ToArray());
            }
            else
            {
                PrintItem(sb, colLen, "Key Area Encryption Key:", nca.Header.KeyAreaKeyIndex);
                sb.AppendLine("Key Area (Encrypted):");
                for (int i = 0; i < 4; i++)
                {
                    PrintItem(sb, colLen, $"    Key {i} (Encrypted):", nca.Header.GetEncryptedKey(i).ToArray());
                }

                sb.AppendLine("Key Area (Decrypted):");
                for (int i = 0; i < 4; i++)
                {
                    PrintItem(sb, colLen, $"    Key {i} (Decrypted):", nca.GetDecryptedKey(i));
                }
            }

            PrintSections();

            return(sb.ToString());

            void PrintSections()
            {
                sb.AppendLine("Sections:");

                for (int i = 0; i < 4; i++)
                {
                    if (!nca.Header.IsSectionEnabled(i))
                    {
                        continue;
                    }

                    NcaFsHeader sectHeader = nca.Header.GetFsHeader(i);
                    bool        isExefs    = nca.Header.ContentType == NcaContentType.Program && i == 0;

                    sb.AppendLine($"    Section {i}:");
                    PrintItem(sb, colLen, "        Offset:", $"0x{nca.Header.GetSectionStartOffset(i):x12}");
                    PrintItem(sb, colLen, "        Size:", $"0x{nca.Header.GetSectionSize(i):x12}");
                    PrintItem(sb, colLen, "        Partition Type:", (isExefs ? "ExeFS" : sectHeader.FormatType.ToString()) + (sectHeader.IsPatchSection() ? " patch" : ""));
                    PrintItem(sb, colLen, "        Section CTR:", $"{sectHeader.Counter:x16}");
                    PrintItem(sb, colLen, "        Section Validity:", $"{ncaHolder.Validities[i]}");

                    switch (sectHeader.HashType)
                    {
                    case NcaHashType.Sha256:
                        PrintSha256Hash(sectHeader, i);
                        break;

                    case NcaHashType.Ivfc:
                        Validity masterHashValidity = nca.ValidateSectionMasterHash(i);

                        PrintIvfcHashNew(sb, colLen, 8, sectHeader.GetIntegrityInfoIvfc(), IntegrityStorageType.RomFs, masterHashValidity);
                        break;

                    default:
                        sb.AppendLine("        Unknown/invalid superblock!");
                        break;
                    }
                }
            }

            void PrintSha256Hash(NcaFsHeader sect, int index)
            {
                NcaFsIntegrityInfoSha256 hashInfo = sect.GetIntegrityInfoSha256();

                PrintItem(sb, colLen, $"        Master Hash{nca.ValidateSectionMasterHash(index).GetValidityString()}:", hashInfo.MasterHash.ToArray());
                sb.AppendLine($"        Hash Table:");

                PrintItem(sb, colLen, "            Offset:", $"0x{hashInfo.GetLevelOffset(0):x12}");
                PrintItem(sb, colLen, "            Size:", $"0x{hashInfo.GetLevelSize(0):x12}");
                PrintItem(sb, colLen, "            Block Size:", $"0x{hashInfo.BlockSize:x}");
                PrintItem(sb, colLen, "        PFS0 Offset:", $"0x{hashInfo.GetLevelOffset(1):x12}");
                PrintItem(sb, colLen, "        PFS0 Size:", $"0x{hashInfo.GetLevelSize(1):x12}");
            }
        }
コード例 #17
0
 public SectionItem(int sectionIndex, NcaFsHeader ncaFsHeader, NcaItem parentItem)
 {
     FsHeader     = ncaFsHeader;
     SectionIndex = sectionIndex;
     ParentItem   = parentItem ?? throw new ArgumentNullException(nameof(parentItem));
 }