Example #1
0
        private FileStream OpenBBAFile(string path)
        {
            FileStream f = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            f.Position = 0;
            f.Read(b_head, 0, b_head.Length);

            //Read header.
            int h = BitConverter.ToInt32(b_head, 0);

            if (h == s7_bba_head_sig)
            {
                BinaryReader reader = new BinaryReader(f);

                //Add: header reading code.
                //Fill: PAKHead....

                m_head.Header     = Encoding.Default.GetString(b_head, 0, 4);
                m_head.Version    = BitConverter.ToInt32(b_head, 4);
                m_head.HeaderSize = BitConverter.ToInt32(b_head, 8);
                m_head.Magic      = BitConverter.ToInt32(b_head, 12);

                if (m_head.Magic == s7_bba_head_magic)
                {
                    listBox1.Items.Add("BBA container opened.");

                    f.Read(b_header, 0, b_header.Length);

                    BBACrypt.DecryptHeader(b_header, b_header.Length, b_head, b_head.Length);

                    m_header.IndexTableOffset = BitConverter.ToInt64(b_header, 0);
                    m_header.IndexTableSize   = BitConverter.ToInt32(b_header, 8);
                    m_header.IndexTableCRC32  = BitConverter.ToInt32(b_header, 12);
                    m_header.Magic            = BitConverter.ToUInt32(b_header, 16);
                    m_header.Magic2           = BitConverter.ToUInt32(b_header, 20);

                    if (m_header.Magic == s7_bba_header_magic &&
                        m_header.Magic2 == s7_bba_header_magic2)
                    {
                        return(f);
                    }
                    else
                    {
                        listBox1.Items.Add(String.Format("BBA container contains bad magic value: {0:X} {1:X}", m_header.Magic, m_header.Magic2));
                    }
                }
                else
                {
                    listBox1.Items.Add(String.Format("BBA container contains bad magic value: {0:X}", m_head.Magic));
                }
            }
            else
            {
                listBox1.Items.Add("Not Settlers 7 .BBA file");
            }

            f.Close();
            f.Dispose();
            return(null);
        }
Example #2
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);
        }
Example #3
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;
        }
Example #4
0
 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
 {
     BBACrypt.SetMode(comboBox1.SelectedIndex);
 }
Example #5
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();
        }