Exemple #1
0
        private byte[] BuildHashTable()
        {
            int tableSize = CalulateHashTableSize(m_pakList.Count);

            byte[] table = new byte[(tableSize * 8) + 4];

            BinaryWriter bw = new BinaryWriter(new MemoryStream(table));

            bw.Write(tableSize);

            int count = m_pakList.Count;

            for (int i = 0; i < count; i++)
            {
                BBA bba     = (BBA)m_pakList[i];
                int crc     = GetCRC32(bba.FileName);
                int pointer = ((tableSize - 1) & crc);
                int pos     = pointer * 8 + 4;

                while (BitConverter.ToInt64(table, pos) != 0)
                {
                    pointer++;
                    pos = pointer * 8 + 4;
                }
                bw.BaseStream.Position = (long)pos;
                bw.Write(crc);
                bw.Write((int)bba.BBAEntryPositionInTable - 0x114);
            }

            return(table);
        }
Exemple #2
0
        private void AddFileToTree(TreeNode rootNode, string path, BBA bba)
        {
            int i = path.IndexOf("\\");

            if (i != -1)
            {
                string item     = path.Remove(i);
                int    idx      = rootNode.Nodes.IndexOfKey(item);
                string nextItem = path.Substring(item.Length + 1);

                if (idx != -1)
                {
                    AddFileToTree(rootNode.Nodes[idx], nextItem, bba);
                }
                else
                {
                    TreeNode node = rootNode.Nodes.Add(item);
                    node.Name = item;
                    node.SelectedImageIndex = 0;
                    node.ImageIndex         = 1;
                    AddFileToTree(node, nextItem, bba);
                }
            }
            else
            {
                TreeNode node      = rootNode.Nodes.Add(path);
                int      iconIndex = _iconListManager.AddFileIcon(path);

                node.ImageIndex         = iconIndex;
                node.SelectedImageIndex = iconIndex;
                node.Name = path;

                string time = DateTime.FromFileTime(bba.Time).ToString();
                string unk1 = string.Format("{0:X}", bba.Unknown1);
                string unk2 = string.Format("{0:X}", bba.Unknown2);
                string unk3 = string.Format("{0:X}", bba.Unknown3);
                string pcrc = string.Format("{0:X}", bba.PackedCRC32);
                string ucrc = string.Format("{0:X}", bba.UnpackedCRC32);
                string tip  = "File name: " + bba.FileName +
                              "\nOffset: " + bba.Offset.ToString() +
                              "\nPacked size: " + bba.PackedSize.ToString() +
                              "\nUnpacked size: " + bba.UnpackedSize.ToString() +
                              "\nFlags: " + bba.Flags.ToString() +
                              "\nPackedCRC32: " + pcrc +
                              "\nUnpackedCRC32: " + ucrc +
                              "\nisFile: " + bba.IsFile.ToString() +
                              "\nunk1: " + unk1 +
                              "\nunk2: " + unk2 +
                              "\nunk3: " + unk3 +
                              "\nFile time: " + time +
                              "\nOffsetToNextFile:" + String.Format("{0:X}", bba.OffsetToNextFileName) +
                              "\nSizeOfPathToRoot: " + String.Format("{0:X}", bba.SizeOfPathToRootDir);


                node.ToolTipText = tip;
            }
        }
Exemple #3
0
        private void FillTree(TreeNode root)
        {
            int count = m_pakList.Count;

            progressBar1.Maximum = count;
            progressBar1.Step    = 1;
            progressBar1.Value   = 0;

            for (int i = 0; i < count; i++)
            {
                BBA bba = ( BBA )m_pakList[i];

                //if (bba.IsFile == -1)
                AddFileToTree(root, bba.FileName, bba);

                progressBar1.PerformStep();
            }
        }
Exemple #4
0
        private byte[] BuildEntry(BBA bba)
        {
            MemoryStream entry = new MemoryStream(0x40);
            BinaryWriter bw    = new BinaryWriter(entry);

            bw.Write(bba.Time);
            bw.Write(bba.UnpackedSize);
            bw.Write(bba.UnpackedCRC32);
            bw.Write(bba.Flags);
            bw.Write(bba.Unknown1);
            bw.Write(bba.Offset);
            bw.Write(bba.PackedSize);
            bw.Write(bba.PackedCRC32);
            bw.Write(bba.Unknown2);
            bw.Write(bba.Unknown3);
            bw.Write(bba.PathSize);
            bw.Write(bba.SizeOfPathToRootDir);
            bw.Write(bba.IsFile);
            bw.Write(bba.OffsetToNextFileName);

            byte[] buff = entry.GetBuffer();

            return(buff);
        }
Exemple #5
0
        private void GetFilesInfo(DirectoryInfo d, ref int ptrToFirstElement)
        {
            BBA bba;

            DirectoryInfo[] dirs    = d.GetDirectories("*");
            int             pathlen = folderBrowserDialog1.SelectedPath.Length;

            int count = dirs.Length;

            for (int i = 0; i < count; i++)
            {
                bba                     = new BBA();
                bba.FileName            = dirs[i].FullName.Substring(pathlen + 1);
                bba.PathSize            = bba.FileName.Length;
                bba.SizeOfPathToRootDir = bba.PathSize - dirs[i].Name.Length;
                bba.Flags               = (int)BBAFlags.Directory;

                ptrToFirstElement += 0x41;
                ptrToFirstElement += bba.PathSize;
                int len = ptrToFirstElement % 4;
                len = (len == 0) ? 0 : 4 - len;
                ptrToFirstElement += len;
                bba.IsFile         = 0;

                int idx = m_pakList.Add(bba);

                GetFilesInfo(dirs[i], ref ptrToFirstElement);

                if (i == count - 1)
                {
                    bba.OffsetToNextFileName = -1;
                }
                else
                {
                    bba.OffsetToNextFileName = ptrToFirstElement;
                }

                m_pakList[idx] = bba;
            }

            FileInfo[] files;
            files = d.GetFiles("*");
            count = files.Length;

            for (int i = 0; i < count; i++)
            {
                bba                     = new BBA();
                bba.FileName            = files[i].FullName.Substring(pathlen + 1);
                bba.IsFile              = -1;
                bba.PathSize            = bba.FileName.Length;
                bba.SizeOfPathToRootDir = bba.PathSize - files[i].Name.Length;
                bba.Time                = files[i].CreationTime.ToFileTime();
                bba.UnpackedSize        = ( int )files[i].Length;
                bba.Unknown2            = 0x100000;
                if (i == count - 1)
                {
                    bba.OffsetToNextFileName = -1;
                }

                m_pakList.Add(bba);

                ptrToFirstElement += 0x41;
                ptrToFirstElement += bba.PathSize;
                int len = ptrToFirstElement % 4;
                len = (len == 0) ? 0 : 4 - len;
                ptrToFirstElement += len;
            }
        }
Exemple #6
0
        private bool SaveFile(BBA bba, string outDir)
        {
            FileStream   f        = null;
            MemoryStream fStream  = null;
            string       FileName = bba.FileName;
            FileStream   pakFile  = m_fs;

            pakFile.Position = bba.Offset;

            int BytesToWrite = bba.UnpackedSize;
            int BytesToRead  = (bba.PackedSize % 4);

            BytesToRead = (BytesToRead == 0) ? bba.PackedSize : (4 - BytesToRead) + bba.PackedSize;
            int BytesRead = 0;

            try
            {
                f = CreateFile(outDir, FileName);
                if (f == null)
                {
                    return(false);
                }

                if (bba.UnpackedSize == 0)
                {
                    f.Close(); return(true);
                }

                fStream = new MemoryStream(BytesToRead);


                if (fStream == null)
                {
                    f.Close(); return(false);
                }

                byte[] buff = fStream.GetBuffer();


                BBAFlags Flags = (BBAFlags)bba.Flags;

                bool IsFileWriten = false;
                bool Decrypted    = false;
                bool Decompressed = false;

                BytesRead = pakFile.Read(buff, 0, BytesToRead);

                if (BytesRead == 0)
                {
                    f.Close(); return(false);
                }

                if ((Flags & BBAFlags.EncryptedHeader) == BBAFlags.EncryptedHeader)
                {
                    int    count = bba.PackedSize / bba.Unknown2 + 1;
                    byte[] b     = new byte[0x10];
                    for (int i = 0; i < count; i++)
                    {
                        Array.Copy(buff, i * bba.Unknown2, b, 0, 0x10);

                        using (MemoryStream s = new MemoryStream())
                        {
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            byte[] TmpKey = s.GetBuffer();
                            BBACrypt.DecryptFileHeader(b, b.Length, TmpKey, 0x10, false);
                        }

                        Array.Copy(b, 0, buff, i * bba.Unknown2, 0x10);
                    }
                }

                if ((Flags & BBAFlags.EncryptedEntireContent) == BBAFlags.EncryptedEntireContent)
                {
                    IsFileWriten = true;
                    int    count = BytesToRead / bba.Unknown2 + 1;
                    byte[] b     = new byte[0x8000];

                    for (int i = 0; i < count; i++)
                    {
                        int ToDecrypt = ((BytesToRead - (i * bba.Unknown2 + b.Length)) >= 0) ? b.Length : BytesToRead - i * bba.Unknown2;

                        Array.Copy(buff, i * bba.Unknown2, b, 0, ToDecrypt);

                        using (MemoryStream s = new MemoryStream())
                        {
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                            byte[] TmpKey = s.GetBuffer();
                            bool   bRes   = BBACrypt.DecryptIndexTable(b, ToDecrypt, TmpKey, 0x10);
                            if (!bRes)
                            {
                                this.listBox1.Items.Add("Failed to decrypt: " + bba.FileName);
                            }

                            int ToWrite = (ToDecrypt == 0x8000) ? 0x8000 : BytesToWrite - i * bba.Unknown2;
                            f.Write(b, 0, ToWrite);
                        }
                    }
                }


                if ((Flags & BBAFlags.Gziped) == BBAFlags.Gziped &&
                    !Decompressed)
                {
                    IsFileWriten = true;
                    using (MemoryStream m = new MemoryStream(buff))
                    {
                        using (GZipStream Decompress = new GZipStream(m, CompressionMode.Decompress))
                        {
                            MemoryStream DecompressionStream = new MemoryStream(0x10000);
                            byte[]       DecompressionBuffer = DecompressionStream.GetBuffer();
                            int          numRead;
                            while ((numRead = Decompress.Read(DecompressionBuffer, 0, DecompressionBuffer.Length)) != 0)
                            {
                                f.Write(DecompressionBuffer, 0, numRead);
                                BytesToWrite -= numRead;
                            }
                            DecompressionStream.Dispose();
                            DecompressionStream.Close();
                            Decompressed = true;
                        }
                    }
                }


                if (!IsFileWriten)
                {
                    f.Write(buff, 0, bba.PackedSize);
                }


                //                         MemoryStream s = new MemoryStream();
                //
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //                             s.Write(BitConverter.GetBytes(bba.PathSize), 0, 4);
                //
                //                             byte[] TmpKey = s.GetBuffer();
                //                             buff = new byte[bba.UnpackedSize];
                //                             pakFile.Read(buff, 0, buff.Length);
                //
                //                             bool bRes = BBACrypt.DecryptIndexTable(buff, buff.Length, TmpKey, 0x10);
                //
                //                             if (bRes == false)
                //                             {
                //                                 this.listBox1.SelectedItem = listBox1.Items.Add("Failed to decrypt: " + bba.FileName );
                //                             }
                //                             else
                //                             {
                //
                //                             }
                //                      }
            }
            catch (System.Exception ex)
            {
                if (FileName != null)
                {
                    this.listBox1.Items.Add(FileName);
                }

                this.listBox1.Items.Add(ex.Message);
            }

            f.Position = 0;

            int crc32 = Compression.GetStreamCRC32(f);

            if (bba.UnpackedCRC32 != crc32)
            {
                listBox1.Items.Add("CRC mismatch: " + bba.FileName);
            }

            if (f != null)
            {
                f.Close();
            }

            if (fStream != null)
            {
                fStream.Dispose();
                fStream.Close();
            }



            DateTime time = DateTime.FromFileTime(bba.Time);

            File.SetCreationTime(outDir + @"\" + FileName, time);
            File.SetLastWriteTime(outDir + @"\" + FileName, time);
            File.SetLastAccessTime(outDir + @"\" + FileName, time);

            return(true);
        }
Exemple #7
0
        private void ReadFAT(FileStream f)
        {
            //Prepare FAT reader.
            f.Position = m_header.IndexTableOffset;
            byte[] table = new byte[m_header.IndexTableSize];
            f.Read(table, 0, table.Length);
            BBACrypt.DecryptIndexTable(table, table.Length, null, 0);

            //MemoryStream input = new MemoryStream( table );
            m_IndexTable = new MemoryStream(table);
            //Compression.Decompress( input, 8, m_IndexTable, true );

            //input.Dispose();
            //input.Close();

            //table = m_IndexTable.GetBuffer();

            FileStream fs = File.OpenWrite(openFileDialog1.FileName + ".idx");

            fs.Write(table, 0, table.Length);
            fs.Close();

            m_tablehead.OffsetToBBAHeadInTable = BitConverter.ToInt32(table, 0);
            m_tablehead.IndexTableOffset       = BitConverter.ToInt32(table, 4);
            m_tablehead.HashTableOffset        = BitConverter.ToInt32(table, 8);

            m_IndexTable.Position = m_tablehead.IndexTableOffset + 4;
            BinaryReader reader = new BinaryReader(m_IndexTable, Encoding.Default);

            int  count      = BitConverter.ToInt32(table, m_tablehead.IndexTableOffset);
            long TableBegin = m_IndexTable.Position;

            for (int i = 0; i < count; i++)
            {
                BBA bba = new BBA();
                bba.BBAEntryPositionInTable = m_IndexTable.Position;
                bba.Time                 = reader.ReadInt64();
                bba.UnpackedSize         = reader.ReadInt32();
                bba.UnpackedCRC32        = reader.ReadInt32();
                bba.Flags                = reader.ReadInt32();
                bba.Unknown1             = reader.ReadInt32();
                bba.Offset               = reader.ReadInt64();
                bba.PackedSize           = reader.ReadInt32();
                bba.PackedCRC32          = reader.ReadInt32();
                bba.Unknown2             = reader.ReadInt32();
                bba.Unknown3             = reader.ReadInt32();
                bba.PathSize             = reader.ReadInt32();
                bba.SizeOfPathToRootDir  = reader.ReadInt32();
                bba.IsFile               = reader.ReadInt32();
                bba.OffsetToNextFileName = reader.ReadInt32();
                byte[] filename = reader.ReadBytes(bba.PathSize);
                bba.FileName = Encoding.Default.GetString(filename);

                //if( ( bba.Unknown1 + bba.Unknown2 + bba.Unknown3 ) != 0 )
                //{
                //    listBox1.Items.Add("u1: " + bba.Unknown1.ToString() + "u2: " + bba.Unknown2.ToString() + "u3: " + bba.Unknown3.ToString());
                //}

                if (bba.IsFile == -1)
                {
                    m_pakList.Add(bba);
                }
                //else
                //{
                //    m_dirList.Add(bba);
                //}

                int pos = (int)m_IndexTable.Position + 1;
                int x   = (pos % 4);
                pos = (x == 0) ? 0 : 4 - x;
                m_IndexTable.Position += pos + 1;

                //if (bba.OffsetToNextFileName == -1)
                //    break;

                //m_IndexTable.Position = pos;//TableBegin + bba.OffsetToNextFileName;
            }
            listBox1.Items.Add("Files found: " + m_pakList.Count.ToString());
            m_IndexTable.Position = 0;
        }
Exemple #8
0
        private void BuildBBA(object obj)
        {
            DisableControls();
            string saveTo  = saveFileDialog1.FileName;
            string openDir = folderBrowserDialog1.SelectedPath;

            try
            {
                m_fs          = new FileStream(saveTo, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
                m_fs.Position = 0;
                m_fs.Write(new byte[0x50], 0, 0x50);

                int idx = listBox1.Items.Add("Getting Files Info...");
                ClearMembers();
                int aproxsize = 0;
                GetFilesInfo(new DirectoryInfo(openDir), ref aproxsize);
                listBox1.Items[idx] += "OK";

                int count = m_pakList.Count;

                int refresh = 0;
                int counter = 0;
                this.progressBar1.Maximum = count;
                this.progressBar1.Value   = 0;
                this.progressBar1.Step    = 1;

                idx = listBox1.Items.Add("writing data...");

                for (int i = 0; i < count; i++)
                {
                    BBA bba = ( BBA )m_pakList[i];

                    if (bba.IsFile == -1)
                    {
                        string     file = openDir + "\\" + bba.FileName;
                        FileStream f1   = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                        f1.Position       = 0;
                        bba.UnpackedCRC32 = Compression.GetStreamCRC32(f1);
                        f1.Position       = 0;

                        bba.Offset     = m_fs.Position;
                        bba.PackedSize = WriteFile(m_fs, f1, new FileInfo(file));

                        if (bba.PackedSize != bba.UnpackedSize)
                        {
                            bba.Flags = 1;
                        }

                        m_fs.Flush();
                        f1.Close();

                        m_pakList[i] = bba;
                    }

                    this.progressBar1.PerformStep();

                    if (refresh == 100)
                    {
                        this.progressBar1.Refresh();
                        this.listBox1.Refresh();
                        refresh = 0;
                    }

                    refresh++;
                    counter++;
                }
                listBox1.Items[idx] += "OK";

                m_header.IndexTableOffset = m_fs.Position;



                refresh = 0;
                counter = 0;
                this.progressBar1.Maximum = count;
                this.progressBar1.Value   = 0;
                this.progressBar1.Step    = 1;


                idx = listBox1.Items.Add("Generating Index Table and Encrypting Headers...");

                m_IndexTable = new MemoryStream();

                m_IndexTable.Write(new byte[0x110], 0, 0x110);
                m_IndexTable.Write(BitConverter.GetBytes(count), 0, 4);

                int OffsetToNextEntry = 0;

                for (int i = 0; i < count; i++)
                {
                    BBA bba = ( BBA )m_pakList[i];

                    byte[] entry = BuildEntry(bba);

                    if (bba.Flags == 1)
                    {
                        byte[] dataheader = new byte[0x10];
                        m_fs.Position = bba.Offset;
                        m_fs.Read(dataheader, 0, dataheader.Length);

                        BBACrypt.EncryptFileHeader(dataheader, dataheader.Length, entry, entry.Length);

                        m_fs.Position = bba.Offset;
                        m_fs.Write(dataheader, 0, dataheader.Length);
                        m_fs.Position   = bba.Offset;
                        bba.PackedCRC32 = Compression.GetStreamCRC32(m_fs, bba.PackedSize);
                    }
                    else
                    {
                        bba.PackedSize  = bba.UnpackedSize;
                        bba.PackedCRC32 = bba.UnpackedCRC32;
                    }
                    OffsetToNextEntry += entry.Length;
                    OffsetToNextEntry += bba.PathSize + 1;

                    int pos = ( int )m_IndexTable.Position;
                    pos += bba.PathSize + 0x40 + 1;
                    int x = (pos % 4);
                    pos = (x == 0) ? 0 : 4 - x;
                    OffsetToNextEntry += pos;

                    bba.BBAEntryPositionInTable = m_IndexTable.Position;

                    if (bba.IsFile == -1)
                    {
                        if (bba.OffsetToNextFileName != -1)
                        {
                            bba.OffsetToNextFileName = OffsetToNextEntry;
                        }
                    }

                    m_pakList[i] = bba;
                    entry        = BuildEntry(bba);

                    m_IndexTable.Write(entry, 0, entry.Length);
                    m_IndexTable.Write(Encoding.Default.GetBytes(bba.FileName), 0, bba.PathSize);
                    m_IndexTable.Write(new byte[pos + 1], 0, pos + 1);

                    this.progressBar1.PerformStep();

                    if (refresh == 100)
                    {
                        this.progressBar1.Refresh();
                        this.listBox1.Refresh();
                        refresh = 0;
                    }

                    refresh++;
                    counter++;
                }

                int    HashTablePosition = ( int )m_IndexTable.Position;
                byte[] hashtable         = BuildHashTable();
                m_IndexTable.Write(hashtable, 0, hashtable.Length);

                BinaryWriter bw = new BinaryWriter(m_IndexTable);
                m_IndexTable.Position = 0;
                bw.Write(( int )0x40);
                bw.Write(( int )0x110);
                bw.Write(HashTablePosition);
                m_IndexTable.Position = 0x40;
                bw.Write(c_bbaHead, 0, c_bbaHead.Length);
                m_IndexTable.Position = 0x60;
                bw.Write(s7_bba_header_magic);
                bw.Write(s7_bba_header_magic2);
                m_IndexTable.Position = 0x94;
                bw.Write(s7_bba_magic1);
                bw.Write(s7_bba_header_magic);
                m_IndexTable.Position = 0;

                int IndexTableAlignedSize = (int)m_IndexTable.Length;

                int len = (int)m_IndexTable.Length;
                len = (len % 4);
                len = (len == 0) ? 0 : 4 - len;
                if (len != 0)
                {
                    IndexTableAlignedSize += len;
                }

//                 bw = new BinaryWriter( m_IndexTable );
//              bw.Write( ( int )m_IndexTable.Length );

                m_header.IndexTableSize = IndexTableAlignedSize;
                m_IndexTable.Capacity   = IndexTableAlignedSize;

                byte[] idxtable = m_IndexTable.GetBuffer();
                bool   res      = BBACrypt.EncryptIndexTable(idxtable, m_header.IndexTableSize, null, 0);

                m_header.IndexTableCRC32 = GetCRC32(idxtable);
                m_header.Magic           = s7_bba_header_magic;
                m_header.Magic2          = s7_bba_header_magic2;
                m_fs.Position            = m_header.IndexTableOffset;
                m_fs.Write(idxtable, 0, idxtable.Length);
                m_fs.Position = 0;
                m_fs.Write(c_bbaHead, 0, c_bbaHead.Length);
                byte[] header = BuildHeader();
                BBACrypt.EncryptHeader(header, header.Length, c_bbaHead, c_bbaHead.Length);
                m_fs.Write(header, 0, header.Length);
                listBox1.Items[idx] += "OK";
                listBox1.Items.Add("BBA file successfully created.");
            }
            catch (Exception e)
            {
                listBox1.Items.Add(e.Message);
            }

            m_fs.Close();
            m_fs = null;
            EnableControls();
            GC.Collect();
        }