Example #1
0
        public void Open()
        {
            OpenFileDialog ofd = new OpenFileDialog();

            ofd.CheckFileExists = true;
            ofd.Filter          = "LedMusic project files (*.lmp)|*.lmp";

            if (ofd.ShowDialog() == true)
            {
                Stream     fs = ofd.OpenFile();
                IFormatter f  = new BinaryFormatter();
                Savefile   s  = (Savefile)f.Deserialize(fs);
                fs.Close();

                GlobalProperties.Instance.CurrentProjectFile = ofd.FileName;
                GlobalProperties.Instance.LedCount           = s.ledCount;
                GlobalProperties.Instance.BPM        = s.bpm;
                GlobalProperties.Instance.BeatOffset = s.beatOffset;
                GlobalProperties.Instance.FPS        = s.fps;

                BassEngine.Instance.OpenFile(s.musicFile);

                Layers = new ObservableCollection <Layer>(s.layers);
            }
        }
        public void ToggleRecording()
        {
            if (m_Text == null)
            {
                Debug.Log("No text Textmesh Pro Text object specified");
                return;
            }

            if (m_IsRecording)
            {
                // stop
                m_Text.text = "Record";
                m_Time      = 0f;

                WriteFile();
            }
            else
            {
                // start
                m_Text.text = "Stop Recording";

                //init savefile
                m_Time     = 0f;
                m_SaveFile = new Savefile();
            }

            m_IsRecording = !m_IsRecording;
        }
Example #3
0
        private void OpenAllSaves()
        {
            if (SaveDir == null)
            {
                return;
            }

            string[] files = Fs.GetFileSystemEntries(SaveDir, "*");

            foreach (string file in files)
            {
                Savefile save     = null;
                string   saveName = Path.GetFileNameWithoutExtension(file);

                try
                {
                    IStorage storage = Fs.OpenFile(file, FileMode.Open).AsStorage();

                    string sdPath = "/" + Util.GetRelativePath(file, SaveDir).Replace('\\', '/');
                    var    nax0   = new Nax0(Keyset, storage, sdPath, false);
                    save = new Savefile(Keyset, nax0.BaseStorage, IntegrityCheckLevel.None, true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"{ex.Message} File: {file}");
                }

                if (save != null && saveName != null)
                {
                    Saves[saveName] = save;
                }
            }
        }
Example #4
0
        public void LoadContents()
        {
            string dataPath = Path.Combine(Application.persistentDataPath, "nodes.json");

            try
            {
                Savefile loadFile = JsonUtility.FromJson <Savefile>(File.ReadAllText(dataPath));

                List <Node> newNodes = new List <Node>();

                foreach (NodeHierarchy nh in loadFile.nodes)
                {
                    GameObject go = Instantiate(m_NodePrefab, m_ArSpace.transform);
                    Node       n  = go.GetComponent <Node>();

                    go.transform.position = nh.parentPosition;
                    n.position            = nh.parentPosition;

                    go.name    = nh.parentName;
                    n.nodeName = nh.parentName;

                    newNodes.Add(n);
                }

                for (int i = 0; i < newNodes.Count; i++)
                {
                    List <Node> c = new List <Node>();

                    foreach (string s in loadFile.nodes[i].childrenNames)
                    {
                        GameObject go = GameObject.Find(s);
                        if (go)
                        {
                            Node n = go.GetComponent <Node>();
                            if (n != null)
                            {
                                c.Add(n);
                            }
                        }
                    }
                    newNodes[i].neighbours = c;
                }
            }
            catch (FileNotFoundException e)
            {
                Debug.LogError(dataPath + " not found\nNo objects loaded: " + e.Message);
            }
        }
Example #5
0
        public void Save()
        {
            if (GlobalProperties.Instance.CurrentProjectFile == null ||
                GlobalProperties.Instance.CurrentProjectFile == "")
            {
                SaveAs();
                return;
            }

            List <Layer> layersList = new List <Layer>(_layers);
            FileStream   fs         = new FileStream(GlobalProperties.Instance.CurrentProjectFile, FileMode.Create);

            Savefile   s = new Savefile(layersList);
            IFormatter f = new BinaryFormatter();

            f.Serialize(fs, s);
            fs.Close();
        }
Example #6
0
        public void SaveNodes(List <Node> nodes)
        {
            Savefile savefile = new Savefile();

            List <NodeHierarchy> nodeHierarchies = new List <NodeHierarchy>();
            List <string>        names           = new List <string>();
            List <Vector3>       positions       = new List <Vector3>();

            foreach (Node node in nodes)
            {
                if (node.includeInSave)
                {
                    NodeHierarchy nh = new NodeHierarchy();
                    nh.parent   = node;
                    nh.children = node.neighbours;

                    List <string> neighbourNames = new List <string>();

                    foreach (Node n in node.neighbours)
                    {
                        if (n != null)
                        {
                            neighbourNames.Add(n.nodeName);
                        }
                    }

                    nh.childrenNames  = neighbourNames;
                    nh.parentName     = node.nodeName;
                    nh.parentPosition = node.position;
                    nodeHierarchies.Add(nh);
                    names.Add(node.nodeName);
                    positions.Add(node.position);
                }
            }

            savefile.nodes = nodeHierarchies;

            string jsonstring = JsonUtility.ToJson(savefile, true);
            string dataPath   = Path.Combine(Application.persistentDataPath, "nodes.json");

            File.WriteAllText(dataPath, jsonstring);
            Debug.Log(Application.persistentDataPath);
        }
        public void LoadContents()
        {
            string dataPath = Path.Combine(Application.persistentDataPath, m_Filename);

            try
            {
                Savefile loadFile = JsonUtility.FromJson <Savefile>(File.ReadAllText(dataPath));

                foreach (Vector3 pos in loadFile.positions)
                {
                    GameObject go = Instantiate(m_ContentPrefab, m_ARSpace.transform);
                    go.transform.localPosition = pos;
                }
            }
            catch (FileNotFoundException e)
            {
                Debug.LogError(dataPath + " not found\nNo objects loaded: " + e.Message);
            }
        }
Example #8
0
        private static List <Ticket> ReadTickets(Keyset keyset, Stream savefile)
        {
            var tickets    = new List <Ticket>();
            var save       = new Savefile(keyset, savefile, false);
            var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin"));
            var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin"));

            var titleId = ticketList.ReadUInt64();

            while (titleId != ulong.MaxValue)
            {
                ticketList.BaseStream.Position += 0x18;
                var start = ticketFile.BaseStream.Position;
                tickets.Add(new Ticket(ticketFile));
                ticketFile.BaseStream.Position = start + 0x400;
                titleId = ticketList.ReadUInt64();
            }

            return(tickets);
        }
Example #9
0
        private static List <Ticket> ReadTickets(Keyset keyset, Stream savefile)
        {
            var tickets    = new List <Ticket>();
            var save       = new Savefile(keyset, savefile.AsStorage(), IntegrityCheckLevel.None, true);
            var ticketList = new BinaryReader(save.OpenFile("/ticket_list.bin").AsStream());
            var ticketFile = new BinaryReader(save.OpenFile("/ticket.bin").AsStream());

            ulong titleId = ticketList.ReadUInt64();

            while (titleId != ulong.MaxValue)
            {
                ticketList.BaseStream.Position += 0x18;
                long start = ticketFile.BaseStream.Position;
                tickets.Add(new Ticket(ticketFile));
                ticketFile.BaseStream.Position = start + 0x400;
                titleId = ticketList.ReadUInt64();
            }

            return(tickets);
        }
Example #10
0
        public void LoadContents()
        {
            string dataPath = Path.Combine(Application.persistentDataPath, m_Filename);

            Debug.Log(string.Format("Trying to load file: {0}", dataPath));

            try
            {
                Savefile loadFile = JsonUtility.FromJson <Savefile>(File.ReadAllText(dataPath));

                foreach (Vector3 pos in loadFile.positions)
                {
                    GameObject go = Instantiate(m_ContentPrefab, m_ARSpace.transform);
                    go.transform.localPosition = pos;
                }

                Debug.Log("Successfully loaded file!");
            }
            catch (FileNotFoundException e)
            {
                Debug.Log(e.Message + "\n.json file for content storage not found. Created a new file!");
                File.WriteAllText(dataPath, "");
            }
        }
Example #11
0
        private static string Print(this Savefile save)
        {
            int colLen = 25;
            var sb     = new StringBuilder();

            sb.AppendLine();

            sb.AppendLine("Savefile:");
            PrintItem(sb, colLen, $"CMAC Signature{save.Header.SignatureValidity.GetValidityString()}:", save.Header.Cmac);
            PrintItem(sb, colLen, "Title ID:", $"{save.Header.ExtraData.TitleId:x16}");
            PrintItem(sb, colLen, "User ID:", save.Header.ExtraData.UserId);
            PrintItem(sb, colLen, "Save ID:", $"{save.Header.ExtraData.SaveId:x16}");
            PrintItem(sb, colLen, "Save Type:", $"{save.Header.ExtraData.Type}");
            PrintItem(sb, colLen, "Owner ID:", $"{save.Header.ExtraData.SaveOwnerId:x16}");
            PrintItem(sb, colLen, "Timestamp:", $"{DateTimeOffset.FromUnixTimeSeconds(save.Header.ExtraData.Timestamp):yyyy-MM-dd HH:mm:ss} UTC");
            PrintItem(sb, colLen, "Save Data Size:", $"0x{save.Header.ExtraData.DataSize:x16} ({Util.GetBytesReadable(save.Header.ExtraData.DataSize)})");
            PrintItem(sb, colLen, "Journal Size:", $"0x{save.Header.ExtraData.JournalSize:x16} ({Util.GetBytesReadable(save.Header.ExtraData.JournalSize)})");
            PrintItem(sb, colLen, $"Header Hash{save.Header.HeaderHashValidity.GetValidityString()}:", save.Header.Layout.Hash);
            PrintItem(sb, colLen, "Number of Files:", save.Files.Length);

            PrintIvfcHash(sb, colLen, 4, save.Header.Ivfc, IntegrityStreamType.Save);

            return(sb.ToString());
        }
Example #12
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));
        }
Example #13
0
        public static void Process(Context ctx)
        {
            using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite))
            {
                var save = new Savefile(ctx.Keyset, file, ctx.Options.IntegrityLevel);

                if (ctx.Options.Validate)
                {
                    save.Verify(ctx.Logger);
                }

                if (ctx.Options.OutDir != null)
                {
                    save.Extract(ctx.Options.OutDir, ctx.Logger);
                }

                if (ctx.Options.DebugOutDir != null)
                {
                    string dir = ctx.Options.DebugOutDir;
                    Directory.CreateDirectory(dir);

                    FsLayout layout = save.Header.Layout;

                    File.WriteAllBytes(Path.Combine(dir, "L0_0_MasterHashA"), save.Header.MasterHashA);
                    File.WriteAllBytes(Path.Combine(dir, "L0_1_MasterHashB"), save.Header.MasterHashB);
                    File.WriteAllBytes(Path.Combine(dir, "L0_2_DuplexMasterA"), save.Header.DuplexMasterA);
                    File.WriteAllBytes(Path.Combine(dir, "L0_3_DuplexMasterB"), save.Header.DuplexMasterB);

                    Stream duplexL1A   = save.DataRemapStorage.OpenStream(layout.DuplexL1OffsetA, layout.DuplexL1Size);
                    Stream duplexL1B   = save.DataRemapStorage.OpenStream(layout.DuplexL1OffsetB, layout.DuplexL1Size);
                    Stream duplexDataA = save.DataRemapStorage.OpenStream(layout.DuplexDataOffsetA, layout.DuplexDataSize);
                    Stream duplexDataB = save.DataRemapStorage.OpenStream(layout.DuplexDataOffsetB, layout.DuplexDataSize);
                    Stream journalData = save.DataRemapStorage.OpenStream(layout.JournalDataOffset, layout.JournalDataSizeB + layout.SizeReservedArea);

                    duplexL1A.WriteAllBytes(Path.Combine(dir, "L0_4_DuplexL1A"), ctx.Logger);
                    duplexL1B.WriteAllBytes(Path.Combine(dir, "L0_5_DuplexL1B"), ctx.Logger);
                    duplexDataA.WriteAllBytes(Path.Combine(dir, "L0_6_DuplexDataA"), ctx.Logger);
                    duplexDataB.WriteAllBytes(Path.Combine(dir, "L0_7_DuplexDataB"), ctx.Logger);
                    journalData.WriteAllBytes(Path.Combine(dir, "L0_9_JournalData"), ctx.Logger);
                    save.DuplexData.WriteAllBytes(Path.Combine(dir, "L1_0_DuplexData"), ctx.Logger);

                    Stream journalTable = save.MetaRemapStorage.OpenStream(layout.JournalTableOffset, layout.JournalTableSize);
                    Stream journalBitmapUpdatedPhysical = save.MetaRemapStorage.OpenStream(layout.JournalBitmapUpdatedPhysicalOffset, layout.JournalBitmapUpdatedPhysicalSize);
                    Stream journalBitmapUpdatedVirtual  = save.MetaRemapStorage.OpenStream(layout.JournalBitmapUpdatedVirtualOffset, layout.JournalBitmapUpdatedVirtualSize);
                    Stream journalBitmapUnassigned      = save.MetaRemapStorage.OpenStream(layout.JournalBitmapUnassignedOffset, layout.JournalBitmapUnassignedSize);
                    Stream journalLayer1Hash            = save.MetaRemapStorage.OpenStream(layout.IvfcL1Offset, layout.IvfcL1Size);
                    Stream journalLayer2Hash            = save.MetaRemapStorage.OpenStream(layout.IvfcL2Offset, layout.IvfcL2Size);
                    Stream journalLayer3Hash            = save.MetaRemapStorage.OpenStream(layout.IvfcL3Offset, layout.IvfcL3Size);
                    Stream journalFat = save.MetaRemapStorage.OpenStream(layout.FatOffset, layout.FatSize);

                    journalTable.WriteAllBytes(Path.Combine(dir, "L2_0_JournalTable"), ctx.Logger);
                    journalBitmapUpdatedPhysical.WriteAllBytes(Path.Combine(dir, "L2_1_JournalBitmapUpdatedPhysical"), ctx.Logger);
                    journalBitmapUpdatedVirtual.WriteAllBytes(Path.Combine(dir, "L2_2_JournalBitmapUpdatedVirtual"), ctx.Logger);
                    journalBitmapUnassigned.WriteAllBytes(Path.Combine(dir, "L2_3_JournalBitmapUnassigned"), ctx.Logger);
                    journalLayer1Hash.WriteAllBytes(Path.Combine(dir, "L2_4_Layer1Hash"), ctx.Logger);
                    journalLayer2Hash.WriteAllBytes(Path.Combine(dir, "L2_5_Layer2Hash"), ctx.Logger);
                    journalLayer3Hash.WriteAllBytes(Path.Combine(dir, "L2_6_Layer3Hash"), ctx.Logger);
                    journalFat.WriteAllBytes(Path.Combine(dir, "L2_7_FAT"), ctx.Logger);

                    save.IvfcStreamSource.CreateStream().WriteAllBytes(Path.Combine(dir, "L3_0_SaveData"), ctx.Logger);
                }

                if (ctx.Options.SignSave)
                {
                    if (save.CommitHeader(ctx.Keyset))
                    {
                        ctx.Logger.LogMessage("Successfully signed save file");
                    }
                    else
                    {
                        ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?");
                    }
                }

                if (ctx.Options.ListFiles)
                {
                    foreach (FileEntry fileEntry in save.Files)
                    {
                        ctx.Logger.LogMessage(fileEntry.FullPath);
                    }
                }

                ctx.Logger.LogMessage(save.Print());
            }
        }
Example #14
0
        public static void Process(Context ctx)
        {
            using (var file = new FileStream(ctx.Options.InFile, FileMode.Open, FileAccess.ReadWrite))
            {
                var save = new Savefile(ctx.Keyset, file.AsStorage(), ctx.Options.IntegrityLevel, true);

                if (ctx.Options.Validate)
                {
                    save.Verify(ctx.Logger);
                }

                if (ctx.Options.OutDir != null)
                {
                    save.Extract(ctx.Options.OutDir, ctx.Logger);
                }

                if (ctx.Options.DebugOutDir != null)
                {
                    // todo
                    string dir = ctx.Options.DebugOutDir;
                    Directory.CreateDirectory(dir);

                    FsLayout layout = save.Header.Layout;

                    string mainRemapDir = Path.Combine(dir, "main_remap");
                    Directory.CreateDirectory(mainRemapDir);

                    save.DataRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Data"));
                    save.DataRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Header"));
                    save.DataRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(mainRemapDir, "Map entries"));

                    string metadataRemapDir = Path.Combine(dir, "metadata_remap");
                    Directory.CreateDirectory(metadataRemapDir);

                    save.MetaRemapStorage.GetBaseStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Data"));
                    save.MetaRemapStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Header"));
                    save.MetaRemapStorage.GetMapEntryStorage().WriteAllBytes(Path.Combine(metadataRemapDir, "Map entries"));

                    string journalDir = Path.Combine(dir, "journal");
                    Directory.CreateDirectory(journalDir);

                    save.JournalStorage.GetBaseStorage().WriteAllBytes(Path.Combine(journalDir, "Data"));
                    save.JournalStorage.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Header"));
                    save.JournalStorage.Map.GetHeaderStorage().WriteAllBytes(Path.Combine(journalDir, "Map_header"));
                    save.JournalStorage.Map.GetMapStorage().WriteAllBytes(Path.Combine(journalDir, "Map"));
                    save.JournalStorage.Map.GetModifiedPhysicalBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "ModifiedPhysicalBlocks"));
                    save.JournalStorage.Map.GetModifiedVirtualBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "ModifiedVirtualBlocks"));
                    save.JournalStorage.Map.GetFreeBlocksStorage().WriteAllBytes(Path.Combine(journalDir, "FreeBlocks"));

                    string saveDir = Path.Combine(dir, "save");
                    Directory.CreateDirectory(saveDir);

                    save.SaveFs.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Header"));
                    save.SaveFs.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "Save_Data"));
                    save.SaveFs.AllocationTable.GetHeaderStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_header"));
                    save.SaveFs.AllocationTable.GetBaseStorage().WriteAllBytes(Path.Combine(saveDir, "FAT_Data"));

                    save.Header.DataIvfcMaster.WriteAllBytes(Path.Combine(saveDir, "Save_MasterHash"));

                    IStorage saveLayer1Hash = save.MetaRemapStorage.Slice(layout.IvfcL1Offset, layout.IvfcL1Size);
                    IStorage saveLayer2Hash = save.MetaRemapStorage.Slice(layout.IvfcL2Offset, layout.IvfcL2Size);
                    IStorage saveLayer3Hash = save.MetaRemapStorage.Slice(layout.IvfcL3Offset, layout.IvfcL3Size);

                    saveLayer1Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer1Hash"), ctx.Logger);
                    saveLayer2Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer2Hash"), ctx.Logger);
                    saveLayer3Hash.WriteAllBytes(Path.Combine(saveDir, "Save_Layer3Hash"), ctx.Logger);

                    string duplexDir = Path.Combine(dir, "duplex");
                    Directory.CreateDirectory(duplexDir);

                    save.Header.DuplexMasterBitmapA.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapA"));
                    save.Header.DuplexMasterBitmapB.WriteAllBytes(Path.Combine(duplexDir, "MasterBitmapB"));

                    IStorage duplexL1A   = save.DataRemapStorage.Slice(layout.DuplexL1OffsetA, layout.DuplexL1Size);
                    IStorage duplexL1B   = save.DataRemapStorage.Slice(layout.DuplexL1OffsetB, layout.DuplexL1Size);
                    IStorage duplexDataA = save.DataRemapStorage.Slice(layout.DuplexDataOffsetA, layout.DuplexDataSize);
                    IStorage duplexDataB = save.DataRemapStorage.Slice(layout.DuplexDataOffsetB, layout.DuplexDataSize);

                    duplexL1A.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapA"), ctx.Logger);
                    duplexL1B.WriteAllBytes(Path.Combine(duplexDir, "L1BitmapB"), ctx.Logger);
                    duplexDataA.WriteAllBytes(Path.Combine(duplexDir, "DataA"), ctx.Logger);
                    duplexDataB.WriteAllBytes(Path.Combine(duplexDir, "DataB"), ctx.Logger);
                }

                if (ctx.Options.SignSave)
                {
                    if (save.CommitHeader(ctx.Keyset))
                    {
                        ctx.Logger.LogMessage("Successfully signed save file");
                    }
                    else
                    {
                        ctx.Logger.LogMessage("Unable to sign save file. Do you have all the required keys?");
                    }
                }

                if (ctx.Options.ListFiles)
                {
                    foreach (FileEntry fileEntry in save.Files)
                    {
                        ctx.Logger.LogMessage(fileEntry.FullPath);
                    }
                }

                ctx.Logger.LogMessage(save.Print());
            }
        }