Exemplo n.º 1
0
        private static void BuildRomFS()
        {
            ROOT_DIR = FullPath;
            FileNameTable FNT = new FileNameTable(ROOT_DIR);

            RomfsFile[]           RomFiles = new RomfsFile[FNT.NumFiles];
            LayoutManager.Input[] In       = new LayoutManager.Input[FNT.NumFiles];
            Console.WriteLine("Creating Layout...");
            for (int i = 0; i < FNT.NumFiles; i++)
            {
                In[i]               = new LayoutManager.Input();
                In[i].FilePath      = FNT.NameEntryTable[i].FullName;
                In[i].AlignmentSize = 0x10;
            }
            LayoutManager.Output[] Out = LayoutManager.Create(In);
            for (int i = 0; i < Out.Length; i++)
            {
                RomFiles[i]          = new RomfsFile();
                RomFiles[i].Offset   = Out[i].Offset;
                RomFiles[i].PathName = Out[i].FilePath.Replace(Path.GetFullPath(ROOT_DIR), "").Replace("\\", "/");
                RomFiles[i].FullName = Out[i].FilePath;
                RomFiles[i].Size     = Out[i].Size;
            }
            using (MemoryStream memoryStream = new MemoryStream())
            {
                Console.WriteLine("Creating RomFS MetaData...");
                MetaDataBuilder mdb = new MetaDataBuilder();
                mdb.BuildRomFSHeader(memoryStream, RomFiles, ROOT_DIR);
                MakeRomFSData(RomFiles, memoryStream);
            }
        }
Exemplo n.º 2
0
        public void BuildRomFSHeader(MemoryStream romfs_stream, RomfsFile[] Entries, string DIR)
        {
            ROOT_DIR = DIR;

            Romfs_MetaData MetaData = new Romfs_MetaData();

            InitializeMetaData(MetaData);

            CalcRomfsSize(MetaData);

            PopulateRomfs(MetaData, Entries);

            WriteMetaDataToStream(MetaData, romfs_stream);
        }
Exemplo n.º 3
0
        private void BuildRomFS()
        {
            this.isWorkerThreadAlive = true;
            ROOT_DIR = TB_Path.Text;
            FileNameTable FNT = new FileNameTable(ROOT_DIR);

            RomfsFile[]           RomFiles = new RomfsFile[FNT.NumFiles];
            LayoutManager.Input[] In       = new LayoutManager.Input[FNT.NumFiles];
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Creating Layout...")));
            for (int i = 0; i < FNT.NumFiles; i++)
            {
                In[i]               = new LayoutManager.Input();
                In[i].FilePath      = FNT.NameEntryTable[i].FullName;
                In[i].AlignmentSize = 0x10;
            }
            LayoutManager.Output[] Out = LayoutManager.Create(In);
            for (int i = 0; i < Out.Length; i++)
            {
                RomFiles[i]          = new RomfsFile();
                RomFiles[i].Offset   = Out[i].Offset;
                RomFiles[i].PathName = Out[i].FilePath.Replace(Path.GetFullPath(ROOT_DIR), "").Replace("\\", "/");
                RomFiles[i].FullName = Out[i].FilePath;
                RomFiles[i].Size     = Out[i].Size;
            }
            using (MemoryStream memoryStream = new MemoryStream())
            {
                TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Creating RomFS MetaData...")));
                MetaDataBuilder mdb = new MetaDataBuilder();
                mdb.BuildRomFSHeader(memoryStream, RomFiles, ROOT_DIR);
                MakeRomFSData(RomFiles, memoryStream);
            }
            this.isWorkerThreadAlive = false;
            Invoke((Action)(() =>
            {
                B_Go.Enabled = true;
                B_Open.Enabled = true;
            }
                            ));
        }
Exemplo n.º 4
0
 public static ulong GetDataBlockLength(RomfsFile[] files, ulong PreData)
 {
     return (files.Length == 0) ? PreData : PreData + files[files.Length - 1].Offset + files[files.Length - 1].Size;
 }
Exemplo n.º 5
0
        private void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata)
        {
            TempFile = Path.GetRandomFileName();
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Computing IVFC Header Data...")));
            IVFCInfo ivfc = new IVFCInfo();
            ivfc.Levels = new IVFCLevel[3];
            for (int i = 0; i < ivfc.Levels.Length; i++)
            {
                ivfc.Levels[i] = new IVFCLevel();
                ivfc.Levels[i].BlockSize = 0x1000;
            }
            ivfc.Levels[2].DataLength = RomfsFile.GetDataBlockLength(RomFiles, (ulong)metadata.Length);
            ivfc.Levels[1].DataLength = (Align(ivfc.Levels[2].DataLength, ivfc.Levels[2].BlockSize) / ivfc.Levels[2].BlockSize) * 0x20; //0x20 per SHA256 hash
            ivfc.Levels[0].DataLength = (Align(ivfc.Levels[1].DataLength, ivfc.Levels[1].BlockSize) / ivfc.Levels[1].BlockSize) * 0x20; //0x20 per SHA256 hash
            ulong MasterHashLen = (Align(ivfc.Levels[0].DataLength, ivfc.Levels[0].BlockSize) / ivfc.Levels[0].BlockSize) * 0x20;
            ulong lofs = 0;
            for (int i = 0; i < ivfc.Levels.Length; i++)
            {
                ivfc.Levels[i].HashOffset = lofs;
                lofs += Align(ivfc.Levels[i].DataLength, ivfc.Levels[i].BlockSize);
            }
            uint IVFC_MAGIC = 0x43465649; //IVFC
            uint RESERVED = 0x0;
            uint HeaderLen = 0x5C;
            uint MEDIA_UNIT_SIZE = 0x200;
            byte[] SuperBlockHash = new byte[0x20];
            FileStream OutFileStream = new FileStream(TempFile, FileMode.Create, FileAccess.ReadWrite);
            try
            {
                OutFileStream.Seek(0, SeekOrigin.Begin);
                OutFileStream.Write(BitConverter.GetBytes(IVFC_MAGIC), 0, 0x4);
                OutFileStream.Write(BitConverter.GetBytes(0x10000), 0, 0x4);
                OutFileStream.Write(BitConverter.GetBytes(MasterHashLen), 0, 0x4);
                for (int i = 0; i < ivfc.Levels.Length; i++)
                {
                    OutFileStream.Write(BitConverter.GetBytes(ivfc.Levels[i].HashOffset), 0, 0x8);
                    OutFileStream.Write(BitConverter.GetBytes(ivfc.Levels[i].DataLength), 0, 0x8);
                    OutFileStream.Write(BitConverter.GetBytes((int)(Math.Log(ivfc.Levels[i].BlockSize, 2))), 0, 0x4);
                    OutFileStream.Write(BitConverter.GetBytes(RESERVED), 0, 0x4);
                }
                OutFileStream.Write(BitConverter.GetBytes(HeaderLen), 0, 0x4);
                //IVFC Header is Written.
                OutFileStream.Seek((long)Align(MasterHashLen + 0x60, ivfc.Levels[0].BlockSize), SeekOrigin.Begin);
                byte[] metadataArray = metadata.ToArray();
                OutFileStream.Write(metadataArray, 0, metadataArray.Length);
                long baseOfs = OutFileStream.Position;
                TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Writing Level 2 Data...")));
                PB_Show.Invoke((Action)(() =>
                {
                    PB_Show.Minimum = 0;
                    PB_Show.Maximum = RomFiles.Length;
                    PB_Show.Value = 0;
                    PB_Show.Step = 1;
                }));
                for (int i = 0; i < RomFiles.Length; i++)
                {
                    OutFileStream.Seek((long)(baseOfs + (long)RomFiles[i].Offset), SeekOrigin.Begin);
                    using (FileStream inStream = new FileStream(RomFiles[i].FullName, FileMode.Open, FileAccess.Read))
                    {
                        while (inStream.Position < inStream.Length)
                        {
                            byte[] buffer = new byte[inStream.Length - inStream.Position > 0x100000 ? 0x100000 : inStream.Length - inStream.Position];
                            inStream.Read(buffer, 0, buffer.Length);
                            OutFileStream.Write(buffer, 0, buffer.Length);
                        }
                    }
                    PB_Show.Invoke((Action)(() => PB_Show.PerformStep()));
                }
                long hashBaseOfs = (long)Align((ulong)OutFileStream.Position, ivfc.Levels[2].BlockSize);
                long hOfs = (long)Align(MasterHashLen, ivfc.Levels[0].BlockSize);
                long cOfs = hashBaseOfs + (long)ivfc.Levels[1].HashOffset;
                SHA256Managed sha = new SHA256Managed();
                for (int i = ivfc.Levels.Length - 1; i >= 0; i--)
                {
                    TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Computing Level " + i + " Hashes...")));
                    byte[] buffer = new byte[(int)ivfc.Levels[i].BlockSize];
                    PB_Show.Invoke((Action)(() =>
                    {
                        PB_Show.Minimum = 0;
                        PB_Show.Maximum = (int)(ivfc.Levels[i].DataLength / ivfc.Levels[i].BlockSize);
                        PB_Show.Value = 0;
                        PB_Show.Step = 1;
                    }));
                    for (long ofs = 0; ofs < (long)ivfc.Levels[i].DataLength; ofs += ivfc.Levels[i].BlockSize)
                    {
                        OutFileStream.Seek(hOfs, SeekOrigin.Begin);
                        OutFileStream.Read(buffer, 0, (int)ivfc.Levels[i].BlockSize);
                        hOfs = OutFileStream.Position;
                        byte[] hash = sha.ComputeHash(buffer);
                        OutFileStream.Seek(cOfs, SeekOrigin.Begin);
                        OutFileStream.Write(hash, 0, hash.Length);
                        cOfs = OutFileStream.Position;
                        PB_Show.Invoke((Action)(() => PB_Show.PerformStep()));
                    }
                    if (i == 2)
                    {
                        long len = OutFileStream.Position;
                        if (len % 0x1000 != 0)
                        {
                            len = (long)Align((ulong)len, 0x1000);
                            byte[] buf = new byte[len - OutFileStream.Position];
                            OutFileStream.Write(buf, 0, buf.Length);
                        }
                    }
                    if (i > 0)
                    {
                        hOfs = hashBaseOfs + (long)ivfc.Levels[i - 1].HashOffset;
                        if (i > 1)
                        {
                            cOfs = hashBaseOfs + (long)ivfc.Levels[i - 2].HashOffset;
                        }
                        else
                        {
                            cOfs = (long)Align(HeaderLen, PADDING_ALIGN);
                        }
                    }
                }
                OutFileStream.Seek(0, SeekOrigin.Begin);
                uint SuperBlockLen = (uint)Align(MasterHashLen + 0x60, MEDIA_UNIT_SIZE);
                byte[] MasterHashes = new byte[SuperBlockLen];
                OutFileStream.Read(MasterHashes, 0, (int)SuperBlockLen);
                SuperBlockHash = sha.ComputeHash(MasterHashes);
            }
            finally
            {
                if (OutFileStream != null)
                    OutFileStream.Dispose();
            }
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("RomFS Super Block Hash: " + ByteArrayToString(SuperBlockHash))));
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Prompting to Save...")));
            SaveFileDialog sfd = new SaveFileDialog();
            Invoke((Action)(() =>
            {
                if (sfd.ShowDialog() == DialogResult.OK)
                {

                    TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Writing Binary to " + sfd.FileName + "...")));
                    Thread thread = new Thread(() => WriteBinary(TempFile, sfd.FileName));
                    thread.IsBackground = true;
                    thread.Start();

                }
            }));
        }
Exemplo n.º 6
0
 private void BuildRomFS()
 {
     this.isWorkerThreadAlive = true;
     ROOT_DIR = TB_Path.Text;
     FileNameTable FNT = new FileNameTable(ROOT_DIR);
     RomfsFile[] RomFiles = new RomfsFile[FNT.NumFiles];
     LayoutManager.Input[] In = new LayoutManager.Input[FNT.NumFiles];
     TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Creating Layout...")));
     for (int i = 0; i < FNT.NumFiles; i++)
     {
         In[i] = new LayoutManager.Input();
         In[i].FilePath = FNT.NameEntryTable[i].FullName;
         In[i].AlignmentSize = 0x10;
     }
     LayoutManager.Output[] Out = LayoutManager.Create(In);
     for (int i = 0; i < Out.Length; i++)
     {
         RomFiles[i] = new RomfsFile();
         RomFiles[i].Offset = Out[i].Offset;
         RomFiles[i].PathName = Out[i].FilePath.Replace(Path.GetFullPath(ROOT_DIR), "").Replace("\\", "/");
         RomFiles[i].FullName = Out[i].FilePath;
         RomFiles[i].Size = Out[i].Size;
     }
     using (MemoryStream memoryStream = new MemoryStream())
     {
         TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Creating RomFS MetaData...")));
         MetaDataBuilder mdb = new MetaDataBuilder();
         mdb.BuildRomFSHeader(memoryStream, RomFiles, ROOT_DIR);
         MakeRomFSData(RomFiles, memoryStream);
     }
     this.isWorkerThreadAlive = false;
     Invoke((Action)(() =>
     {
         B_Go.Enabled = true;
         B_Open.Enabled = true;
     }
     ));
 }
Exemplo n.º 7
0
        private void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata)
        {
            TempFile = Path.GetRandomFileName();
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Computing IVFC Header Data...")));
            IVFCInfo ivfc = new IVFCInfo();

            ivfc.Levels = new IVFCLevel[3];
            for (int i = 0; i < ivfc.Levels.Length; i++)
            {
                ivfc.Levels[i]           = new IVFCLevel();
                ivfc.Levels[i].BlockSize = 0x1000;
            }
            ivfc.Levels[2].DataLength = RomfsFile.GetDataBlockLength(RomFiles, (ulong)metadata.Length);
            ivfc.Levels[1].DataLength = (Align(ivfc.Levels[2].DataLength, ivfc.Levels[2].BlockSize) / ivfc.Levels[2].BlockSize) * 0x20; //0x20 per SHA256 hash
            ivfc.Levels[0].DataLength = (Align(ivfc.Levels[1].DataLength, ivfc.Levels[1].BlockSize) / ivfc.Levels[1].BlockSize) * 0x20; //0x20 per SHA256 hash
            ulong MasterHashLen = (Align(ivfc.Levels[0].DataLength, ivfc.Levels[0].BlockSize) / ivfc.Levels[0].BlockSize) * 0x20;
            ulong lofs          = 0;

            for (int i = 0; i < ivfc.Levels.Length; i++)
            {
                ivfc.Levels[i].HashOffset = lofs;
                lofs += Align(ivfc.Levels[i].DataLength, ivfc.Levels[i].BlockSize);
            }
            uint IVFC_MAGIC      = 0x43465649; //IVFC
            uint RESERVED        = 0x0;
            uint HeaderLen       = 0x5C;
            uint MEDIA_UNIT_SIZE = 0x200;

            byte[]     SuperBlockHash = new byte[0x20];
            FileStream OutFileStream  = new FileStream(TempFile, FileMode.Create, FileAccess.ReadWrite);

            try
            {
                OutFileStream.Seek(0, SeekOrigin.Begin);
                OutFileStream.Write(BitConverter.GetBytes(IVFC_MAGIC), 0, 0x4);
                OutFileStream.Write(BitConverter.GetBytes(0x10000), 0, 0x4);
                OutFileStream.Write(BitConverter.GetBytes(MasterHashLen), 0, 0x4);
                for (int i = 0; i < ivfc.Levels.Length; i++)
                {
                    OutFileStream.Write(BitConverter.GetBytes(ivfc.Levels[i].HashOffset), 0, 0x8);
                    OutFileStream.Write(BitConverter.GetBytes(ivfc.Levels[i].DataLength), 0, 0x8);
                    OutFileStream.Write(BitConverter.GetBytes((int)(Math.Log(ivfc.Levels[i].BlockSize, 2))), 0, 0x4);
                    OutFileStream.Write(BitConverter.GetBytes(RESERVED), 0, 0x4);
                }
                OutFileStream.Write(BitConverter.GetBytes(HeaderLen), 0, 0x4);
                //IVFC Header is Written.
                OutFileStream.Seek((long)Align(MasterHashLen + 0x60, ivfc.Levels[0].BlockSize), SeekOrigin.Begin);
                byte[] metadataArray = metadata.ToArray();
                OutFileStream.Write(metadataArray, 0, metadataArray.Length);
                long baseOfs = OutFileStream.Position;
                TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Writing Level 2 Data...")));
                PB_Show.Invoke((Action)(() =>
                {
                    PB_Show.Minimum = 0;
                    PB_Show.Maximum = RomFiles.Length;
                    PB_Show.Value = 0;
                    PB_Show.Step = 1;
                }));
                for (int i = 0; i < RomFiles.Length; i++)
                {
                    OutFileStream.Seek((long)(baseOfs + (long)RomFiles[i].Offset), SeekOrigin.Begin);
                    using (FileStream inStream = new FileStream(RomFiles[i].FullName, FileMode.Open, FileAccess.Read))
                    {
                        while (inStream.Position < inStream.Length)
                        {
                            byte[] buffer = new byte[inStream.Length - inStream.Position > 0x100000 ? 0x100000 : inStream.Length - inStream.Position];
                            inStream.Read(buffer, 0, buffer.Length);
                            OutFileStream.Write(buffer, 0, buffer.Length);
                        }
                    }
                    PB_Show.Invoke((Action)(() => PB_Show.PerformStep()));
                }
                long          hashBaseOfs = (long)Align((ulong)OutFileStream.Position, ivfc.Levels[2].BlockSize);
                long          hOfs        = (long)Align(MasterHashLen, ivfc.Levels[0].BlockSize);
                long          cOfs        = hashBaseOfs + (long)ivfc.Levels[1].HashOffset;
                SHA256Managed sha         = new SHA256Managed();
                for (int i = ivfc.Levels.Length - 1; i >= 0; i--)
                {
                    TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Computing Level " + i + " Hashes...")));
                    byte[] buffer = new byte[(int)ivfc.Levels[i].BlockSize];
                    PB_Show.Invoke((Action)(() =>
                    {
                        PB_Show.Minimum = 0;
                        PB_Show.Maximum = (int)(ivfc.Levels[i].DataLength / ivfc.Levels[i].BlockSize);
                        PB_Show.Value = 0;
                        PB_Show.Step = 1;
                    }));
                    for (long ofs = 0; ofs < (long)ivfc.Levels[i].DataLength; ofs += ivfc.Levels[i].BlockSize)
                    {
                        OutFileStream.Seek(hOfs, SeekOrigin.Begin);
                        OutFileStream.Read(buffer, 0, (int)ivfc.Levels[i].BlockSize);
                        hOfs = OutFileStream.Position;
                        byte[] hash = sha.ComputeHash(buffer);
                        OutFileStream.Seek(cOfs, SeekOrigin.Begin);
                        OutFileStream.Write(hash, 0, hash.Length);
                        cOfs = OutFileStream.Position;
                        PB_Show.Invoke((Action)(() => PB_Show.PerformStep()));
                    }
                    if (i == 2)
                    {
                        long len = OutFileStream.Position;
                        if (len % 0x1000 != 0)
                        {
                            len = (long)Align((ulong)len, 0x1000);
                            byte[] buf = new byte[len - OutFileStream.Position];
                            OutFileStream.Write(buf, 0, buf.Length);
                        }
                    }
                    if (i > 0)
                    {
                        hOfs = hashBaseOfs + (long)ivfc.Levels[i - 1].HashOffset;
                        if (i > 1)
                        {
                            cOfs = hashBaseOfs + (long)ivfc.Levels[i - 2].HashOffset;
                        }
                        else
                        {
                            cOfs = (long)Align(HeaderLen, PADDING_ALIGN);
                        }
                    }
                }
                OutFileStream.Seek(0, SeekOrigin.Begin);
                uint   SuperBlockLen = (uint)Align(MasterHashLen + 0x60, MEDIA_UNIT_SIZE);
                byte[] MasterHashes  = new byte[SuperBlockLen];
                OutFileStream.Read(MasterHashes, 0, (int)SuperBlockLen);
                SuperBlockHash = sha.ComputeHash(MasterHashes);
            }
            finally
            {
                if (OutFileStream != null)
                {
                    OutFileStream.Dispose();
                }
            }
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("RomFS Super Block Hash: " + ByteArrayToString(SuperBlockHash))));
            TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Prompting to Save...")));
            SaveFileDialog sfd = new SaveFileDialog();

            Invoke((Action)(() =>
            {
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Writing Binary to " + sfd.FileName + "...")));
                    Thread thread = new Thread(() => WriteBinary(TempFile, sfd.FileName));
                    thread.IsBackground = true;
                    thread.Start();
                }
            }));
        }
Exemplo n.º 8
0
        private void PopulateRomfs(Romfs_MetaData MetaData, RomfsFile[] Entries)
        {
            //Recursively Add All Directories to DirectoryTable
            AddDir(MetaData, new DirectoryInfo(ROOT_DIR), 0, ROMFS_UNUSED_ENTRY);

            //Iteratively Add All Files to FileTable
            AddFiles(MetaData, Entries);

            //Set HashKeyPointers, Build HashTables
            PopulateHashTables(MetaData);

            //Thats it.
        }
Exemplo n.º 9
0
 private void AddFiles(Romfs_MetaData MetaData, RomfsFile[] Entries)
 {
     string PrevDirPath = "";
     for (int i = 0; i < Entries.Length; i++)
     {
         FileInfo file = new FileInfo(Entries[i].FullName);
         Romfs_FileEntry Entry = new Romfs_FileEntry();
         string DirPath = Path.GetDirectoryName(Entries[i].FullName);
         int ParentIndex = GetRomfsDirEntry(MetaData, DirPath);
         Entry.FullName = Entries[i].FullName;
         Entry.Offset = MetaData.FileTableLen;
         Entry.ParentDirOffset = MetaData.DirTable.DirectoryTable[ParentIndex].Offset;
         Entry.SiblingOffset = ROMFS_UNUSED_ENTRY;
         if (DirPath == PrevDirPath)
         {
             MetaData.FileTable.FileTable[i - 1].SiblingOffset = Entry.Offset;
         }
         if (MetaData.DirTable.DirectoryTable[ParentIndex].FileOffset == ROMFS_UNUSED_ENTRY)
         {
             MetaData.DirTable.DirectoryTable[ParentIndex].FileOffset = Entry.Offset;
         }
         Entry.HashKeyPointer = ROMFS_UNUSED_ENTRY;
         Entry.NameSize = (uint)file.Name.Length * 2;
         Entry.Name = file.Name;
         Entry.DataOffset = Entries[i].Offset;
         Entry.DataSize = Entries[i].Size;
         MetaData.FileTable.FileTable.Add(Entry);
         MetaData.FileTableLen += 0x20 + (uint)Align((ulong)file.Name.Length * 2, 4);
         PrevDirPath = DirPath;
     }
 }