예제 #1
0
        /// <summary>
        /// Class Constructor
        /// </summary>
        /// <param name="file">The full path to the TPF file for reading</param>
        /// <param name="treefolder">The path to the directory containing the hash tree files</param>
        /// <param name="FormView">Should the class generate a form to view this TPF</param>
        public TPFExtract(String file, String treefolder, bool FormView)
        {
            _zippy = new ZipReader(file);

            Files = new List<string>();
            foreach (ZipReader.ZipEntryFull entry in _zippy.Entries)
                Files.Add(entry.Filename);

            _trees = new List<HashTree>();
            try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME1Tree.hash"))); }
            catch (FileNotFoundException) { }
            try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME2Tree.hash"))); }
            catch (FileNotFoundException) { }
            try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME3Tree.hash"))); }
            catch (FileNotFoundException) { }

            _formview = FormView;
            if (_formview)
            {
                if (_trees.Count < 3)
                    MessageBox.Show("Some of the hash files weren't found, some of the auto-matching options won't be available", "Missing files", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                TPFView form = new TPFView(this);
                form.Show();
            }
        }
예제 #2
0
        /// <summary>
        /// Class Constructor
        /// </summary>
        /// <param name="file">The full path to the TPF file for reading</param>
        /// <param name="treefolder">The path to the directory containing the hash tree files</param>
        /// <param name="FormView">Should the class generate a form to view this TPF</param>
        public TPFExtract(String file, String treefolder, bool FormView)
        {
            _zippy = new ZipReader(file);

            Files = new List <string>();
            foreach (ZipReader.ZipEntryFull entry in _zippy.Entries)
            {
                Files.Add(entry.Filename);
            }

            _trees = new List <HashTree>();
            try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME1Tree.hash"))); }
            catch (FileNotFoundException) { }
            try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME2Tree.hash"))); }
            catch (FileNotFoundException) { }
            try { _trees.Add(new HashTree(Path.Combine(treefolder, "ME3Tree.hash"))); }
            catch (FileNotFoundException) { }

            _formview = FormView;
            if (_formview)
            {
                if (_trees.Count < 3)
                {
                    MessageBox.Show("Some of the hash files weren't found, some of the auto-matching options won't be available", "Missing files", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                }
                TPFView form = new TPFView(this);
                form.Show();
            }
        }
예제 #3
0
        public static void DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count)
        {
            if (block == null || block.Length < count || count < 12)
                throw new ArgumentException("Invalid arguments for decryption");

            crcgen = new CRC32();
            InitCipher(tpfkey);

            DecryptBlock(block, start, 12);

            if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8)
                throw new FormatException("Incorrect password");

            DecryptBlock(block, start + 12, count - 12);
        }
예제 #4
0
        public static void DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count)
        {
            if (block == null || block.Length < count || count < 12)
                throw new ArgumentException("Invalid arguments for decryption");

            InitCipher(tpfkey);

            DecryptBlock(block, start, 12);

             // KFreon: Apparently not required. Causes some TPF's to fail loading, but when commented out, TPF loads fine, so...
            /*if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8)
                throw new FormatException("Incorrect password");*/

            DecryptBlock(block, start + 12, count - 12);
        }
예제 #5
0
        /// <summary>
        /// Constructor for TPF texture objects.
        /// </summary>
        /// <param name="filename">Filename of texture.</param>
        /// <param name="tpfind">Index of texture inside TPF, if applicable.</param>
        /// <param name="path">Path of texture, if applicable.</param>
        /// <param name="zip">Zippy of TPF, if applicable.</param>
        public TPFTexInfo(string filename, int tpfind, string path, ZipReader zip, int WhichGame)
        {
            FileName = filename;
            TPFInd   = tpfind;
            FilePath = path;

            Files          = new List <string>();
            ExpIDs         = new List <int>();
            Thumbnail      = new MemoryStream();
            OriginalExpIDs = new List <int>();
            OriginalFiles  = new List <string>();
            FileDuplicates = new List <TPFTexInfo>();
            TreeDuplicates = new List <int>();
            zippy          = zip;
            GameVersion    = WhichGame;
        }
예제 #6
0
            public ZipEntryFull(byte[] entry, ZipReader par)
                : base(par)
            {
                if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic)
                {
                    throw new FormatException("Incorrect header");
                }
                Buildvers   = BitConverter.ToUInt16(entry, 4);
                Minvers     = BitConverter.ToUInt16(entry, 6);
                BitFlag     = BitConverter.ToUInt16(entry, 8);
                ComprMethod = BitConverter.ToUInt16(entry, 10);
                ModifyTime  = BitConverter.ToUInt16(entry, 12);
                ModifyDate  = BitConverter.ToUInt16(entry, 14);
                CRC         = BitConverter.ToUInt32(entry, 16);
                ComprSize   = BitConverter.ToUInt32(entry, 20);
                UncomprSize = BitConverter.ToUInt32(entry, 24);
                ushort namelen  = BitConverter.ToUInt16(entry, 28);
                ushort extralen = BitConverter.ToUInt16(entry, 30);
                ushort commlen  = BitConverter.ToUInt16(entry, 32);

                DiskStart    = BitConverter.ToUInt16(entry, 34);
                InternalAttr = BitConverter.ToUInt16(entry, 36);
                ExternalAttr = BitConverter.ToUInt32(entry, 38);
                FileOffset   = BitConverter.ToUInt32(entry, 42);

                char[] strbuild = new char[namelen];
                for (int i = 0; i < namelen; i++)
                {
                    strbuild[i] = (char)entry[46 + i];
                }
                Filename = new string(strbuild);

                Extra = new byte[extralen];
                for (int i = 0; i < extralen; i++)
                {
                    Extra[i] = entry[46 + namelen + i];
                }

                strbuild = new char[commlen];
                for (int i = 0; i < commlen; i++)
                {
                    strbuild[i] = (char)entry[46 + namelen + extralen + i];
                }
                Comment = new string(strbuild);
            }
예제 #7
0
        public static byte[] DecryptData(ZipReader.ZipEntry entry, byte[] block, int start, int count)
        {
            if (block == null || block.Length < count || count < 12)
                throw new ArgumentException("Invalid arguments for decryption");

            UInt32[] Keys = InitCipher(tpfkey);

            // Decrypt crypt header
            DecryptBlock(block, start, 12, Keys); // 12 = crypt header size

            // KFreon: Testing header
            //Console.WriteLine($"crypt header crc: {block[start + 10]}, {block[start + 11]}");

            // KFreon: Doesn't seem to require this
            /*if (block[11] != (byte)((entry.CRC >> 24) & 0xff) && (entry.BitFlag & 0x8) != 0x8)
                Console.WriteLine("Incorrect password");*/

            DecryptBlock(block, start + 12, count - 12, Keys);  // Decrypt main block after crypt header
            return block;
        }
예제 #8
0
            public ZipEntryFull(byte[] entry, ZipReader par)
                : base(par)
            {
                if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic)
                    throw new FormatException("Incorrect header");
                Buildvers = BitConverter.ToUInt16(entry, 4);
                Minvers = BitConverter.ToUInt16(entry, 6);
                BitFlag = BitConverter.ToUInt16(entry, 8);
                ComprMethod = BitConverter.ToUInt16(entry, 10);
                ModifyTime = BitConverter.ToUInt16(entry, 12);
                ModifyDate = BitConverter.ToUInt16(entry, 14);
                CRC = BitConverter.ToUInt32(entry, 16);
                ComprSize = BitConverter.ToUInt32(entry, 20);
                UncomprSize = BitConverter.ToUInt32(entry, 24);
                ushort namelen = BitConverter.ToUInt16(entry, 28);
                ushort extralen = BitConverter.ToUInt16(entry, 30);
                ushort commlen = BitConverter.ToUInt16(entry, 32);
                DiskStart = BitConverter.ToUInt16(entry, 34);
                InternalAttr = BitConverter.ToUInt16(entry, 36);
                ExternalAttr = BitConverter.ToUInt32(entry, 38);
                FileOffset = BitConverter.ToUInt32(entry, 42);

                char[] strbuild = new char[namelen];
                for (int i = 0; i < namelen; i++)
                    strbuild[i] = (char)entry[46 + i];
                Filename = new string(strbuild);

                Extra = new byte[extralen];
                for (int i = 0; i < extralen; i++)
                    Extra[i] = entry[46 + namelen + i];

                strbuild = new char[commlen];
                for (int i = 0; i < commlen; i++)
                    strbuild[i] = (char)entry[46 + namelen + extralen + i];
                Comment = new string(strbuild);
            }
예제 #9
0
            public byte[] Extract(bool Preview, String outname = null)
            {
                byte[] databuff;
                int    dataoff = 30;

                if (Filename != null)
                {
                    dataoff += Filename.Length;
                }
                if (Extra != null)
                {
                    dataoff += Extra.Length;
                }
                using (FileStream tpf = new FileStream(_par._filename, FileMode.Open, FileAccess.Read))
                {
                    tpf.Seek(FileOffset, SeekOrigin.Begin);
                    databuff = ZipReader.BuffXOR(tpf, dataoff + (int)ComprSize + 16); // XOR the whole data block as well as the footer
                }

                // Check for correct header data and such
                ZipEntry fileentry = new ZipEntry(databuff);

                if (!fileentry.Compare(this))
                {
                    throw new InvalidDataException("File header not as expected");
                }
                if (BitConverter.ToUInt32(databuff, (int)ComprSize + dataoff) != datadescriptormagic)
                {
                    throw new InvalidDataException("Footer not as expected");
                }

                //ZipCrypto.DecryptData(this, databuff, dataoff, (int)ComprSize);
                KFreonZipCrypto crypto = new KFreonZipCrypto(this, databuff, dataoff, (int)ComprSize);

                databuff = crypto.GetBlocks();

                databuff = Deflate(databuff, 12 + dataoff, (int)ComprSize - 12);
                if (databuff.Length != UncomprSize)
                {
                    throw new InvalidDataException("Deflation resulted in incorrect file size");
                }
                CRC32 crcgen = new CRC32();

                if (crcgen.BlockChecksum(databuff, 0, (int)UncomprSize) != CRC)
                {
                    throw new InvalidDataException("Checksums don't match");
                }

                if (!Preview)
                {
                    outname = outname ?? Filename;
                    using (FileStream fs = new FileStream(outname, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(databuff, 0, (int)UncomprSize);
                    }
                    return(null);
                }
                else
                {
                    return(databuff);
                }
            }
예제 #10
0
        /// <summary>
        /// Constructor for TPF texture objects. 
        /// </summary>
        /// <param name="filename">Filename of texture.</param>
        /// <param name="tpfind">Index of texture inside TPF, if applicable.</param>
        /// <param name="path">Path of texture, if applicable.</param>
        /// <param name="zip">Zippy of TPF, if applicable.</param>
        public TPFTexInfo(string filename, int tpfind, string path, ZipReader zip, int WhichGame)
        {
            FileName = filename;
            TPFInd = tpfind;
            FilePath = path;

            Files = new List<string>();
            ExpIDs = new List<int>();
            Thumbnail = new MemoryStream();
            OriginalExpIDs = new List<int>();
            OriginalFiles = new List<string>();
            FileDuplicates = new List<TPFTexInfo>();
            TreeDuplicates = new List<int>();
            zippy = zip;
            GameVersion = WhichGame;
        }
예제 #11
0
            public ZipEntryFull(byte[] entry, ZipReader par)
                : base(par)
            {
                if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic)
                    throw new FormatException("Incorrect header");
                Buildvers = BitConverter.ToUInt16(entry, 4);
                Minvers = BitConverter.ToUInt16(entry, 6);
                BitFlag = BitConverter.ToUInt16(entry, 8);
                ComprMethod = BitConverter.ToUInt16(entry, 10);
                ModifyTime = BitConverter.ToUInt16(entry, 12);
                ModifyDate = BitConverter.ToUInt16(entry, 14);
                CRC = BitConverter.ToUInt32(entry, 16);
                ComprSize = BitConverter.ToUInt32(entry, 20);
                UncomprSize = BitConverter.ToUInt32(entry, 24);
                ushort namelen = BitConverter.ToUInt16(entry, 28);
                ushort extralen = BitConverter.ToUInt16(entry, 30);
                ushort commlen = BitConverter.ToUInt16(entry, 32);
                DiskStart = BitConverter.ToUInt16(entry, 34);
                InternalAttr = BitConverter.ToUInt16(entry, 36);
                ExternalAttr = BitConverter.ToUInt32(entry, 38);
                FileOffset = BitConverter.ToUInt32(entry, 42);

                char[] strbuild = new char[namelen];
                for (int i = 0; i < namelen; i++)
                    strbuild[i] = (char)entry[46 + i];
                Filename = new string(strbuild);

                Extra = new byte[extralen];
                for (int i = 0; i < extralen; i++)
                    Extra[i] = entry[46 + namelen + i];

                strbuild = new char[commlen];
                for (int i = 0; i < commlen; i++)
                    strbuild[i] = (char)entry[46 + namelen + extralen + i];
                Comment = new string(strbuild);

                // KFreon: Debugging
                /*Console.WriteLine(Filename);
                Console.WriteLine($"build = {Buildvers}");
                Console.WriteLine($"minvers = {Minvers}");
                Console.WriteLine($"bitflag = {BitFlag}");
                Console.WriteLine($"compr = {ComprMethod}");
                Console.WriteLine($"modifytime = {ModifyTime}");
                Console.WriteLine($"modifydate = {ModifyDate}");
                Console.WriteLine($"crc = {CRC}");
                Console.WriteLine($"comprsize = {ComprSize}");
                Console.WriteLine($"uncsize = {UncomprSize}");
                Console.WriteLine($"namelen = {namelen}");
                Console.WriteLine($"extralen = {extralen}");
                Console.WriteLine($"commlen = {commlen}");
                Console.WriteLine($"diskstart = {DiskStart}");
                Console.WriteLine($"internal = {InternalAttr}");
                Console.WriteLine($"external = {ExternalAttr}");
                Console.WriteLine($"file offset = {FileOffset}");
                Console.WriteLine($"extra = {Extra}");
                Console.WriteLine($"comment = {Comment}");
                Console.WriteLine();*/
            }
예제 #12
0
 public ZipEntry(ZipReader par) { _par = par; }
예제 #13
0
        private void PreviewDef(ZipReader.ZipEntryFull ent)
        {
            try
            {
                byte[] data = ent.Extract(true);
                if (data == null)
                    throw new NullReferenceException("Data returned was null");

                pictureBox1.Visible = false;
                char[] chars = new char[data.Length];
                for (int i = 0; i < data.Length; i++)
                    chars[i] = (char)data[i];
                rtb1.Text = "Texmod.def contents:\n\n" + new string(chars);
            }
            catch (Exception exc)
            {
                MessageBox.Show("An error occurred: " + exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
예제 #14
0
        private void PreviewImg(ZipReader.ZipEntryFull ent)
        {

        }
예제 #15
0
        public TPFTexInfo(string file, ZipReader.ZipEntryFull entry, MEDirectories.MEDirectories gameDirecs) : this(gameDirecs)
        {
            ZipEntry = entry;

            if (Path.IsPathRooted(file))
            {
                FilePath = Path.GetDirectoryName(file);
                FileName = Path.GetFileName(file);
            }
            else
                FileName = file;
        }
예제 #16
0
        private void PreviewTex(ZipReader.ZipEntryFull ent, bool dds)
        {
            try
            {
                Bitmap img;
                if (dds)
                {
                    byte[] data = ent.Extract(true);
                    if (data == null)
                        throw new NullReferenceException("Data returned was null");

                    using (ImageEngineImage ddsimg = new ImageEngineImage(data))
                        img = ddsimg.GetGDIBitmap(true);
                }
                else
                {
                    ent.Extract(false, "preview.tga");
                    img = new TargaImage("preview.tga").Image;
                    File.Delete("preview.tga");
                }
                if (pictureBox1.Image != null)
                    pictureBox1.Image.Dispose();

                if (_resize)
                    pictureBox1.Image = resizeImage(img, new System.Drawing.Size(512, 512));
                else
                    pictureBox1.Image = img;
                pictureBox1.Visible = true;
                pictureBox1.Refresh();
            }
            catch (Exception exc)
            {
                MessageBox.Show("An error occurred: " + exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
예제 #17
0
            public ZipEntryFull(byte[] entry, ZipReader par)
                : base(par)
            {
                if (BitConverter.ToUInt32(entry, 0) != dirfileheadermagic)
                {
                    throw new FormatException("Incorrect header");
                }
                Buildvers   = BitConverter.ToUInt16(entry, 4);
                Minvers     = BitConverter.ToUInt16(entry, 6);
                BitFlag     = BitConverter.ToUInt16(entry, 8);
                ComprMethod = BitConverter.ToUInt16(entry, 10);
                ModifyTime  = BitConverter.ToUInt16(entry, 12);
                ModifyDate  = BitConverter.ToUInt16(entry, 14);
                CRC         = BitConverter.ToUInt32(entry, 16);
                ComprSize   = BitConverter.ToUInt32(entry, 20);
                UncomprSize = BitConverter.ToUInt32(entry, 24);
                ushort namelen  = BitConverter.ToUInt16(entry, 28);
                ushort extralen = BitConverter.ToUInt16(entry, 30);
                ushort commlen  = BitConverter.ToUInt16(entry, 32);

                DiskStart    = BitConverter.ToUInt16(entry, 34);
                InternalAttr = BitConverter.ToUInt16(entry, 36);
                ExternalAttr = BitConverter.ToUInt32(entry, 38);
                FileOffset   = BitConverter.ToUInt32(entry, 42);

                char[] strbuild = new char[namelen];
                for (int i = 0; i < namelen; i++)
                {
                    strbuild[i] = (char)entry[46 + i];
                }
                Filename = new string(strbuild);

                Extra = new byte[extralen];
                for (int i = 0; i < extralen; i++)
                {
                    Extra[i] = entry[46 + namelen + i];
                }

                strbuild = new char[commlen];
                for (int i = 0; i < commlen; i++)
                {
                    strbuild[i] = (char)entry[46 + namelen + extralen + i];
                }
                Comment = new string(strbuild);

                // KFreon: Debugging

                /*Console.WriteLine(Filename);
                 * Console.WriteLine($"build = {Buildvers}");
                 * Console.WriteLine($"minvers = {Minvers}");
                 * Console.WriteLine($"bitflag = {BitFlag}");
                 * Console.WriteLine($"compr = {ComprMethod}");
                 * Console.WriteLine($"modifytime = {ModifyTime}");
                 * Console.WriteLine($"modifydate = {ModifyDate}");
                 * Console.WriteLine($"crc = {CRC}");
                 * Console.WriteLine($"comprsize = {ComprSize}");
                 * Console.WriteLine($"uncsize = {UncomprSize}");
                 * Console.WriteLine($"namelen = {namelen}");
                 * Console.WriteLine($"extralen = {extralen}");
                 * Console.WriteLine($"commlen = {commlen}");
                 * Console.WriteLine($"diskstart = {DiskStart}");
                 * Console.WriteLine($"internal = {InternalAttr}");
                 * Console.WriteLine($"external = {ExternalAttr}");
                 * Console.WriteLine($"file offset = {FileOffset}");
                 * Console.WriteLine($"extra = {Extra}");
                 * Console.WriteLine($"comment = {Comment}");
                 * Console.WriteLine();*/
            }
예제 #18
0
            public byte[] Extract(bool Preview, String outname = null)
            {
                byte[] databuff;
                int    dataoff = 30; // For ZipEntry header - not the above one

                if (Filename != null)
                {
                    dataoff += Filename.Length;
                }
                if (Extra != null)
                {
                    dataoff += Extra.Length;
                }

                // KFreon: Use stored MemoryStream if possible.
                Stream tpf = null;

                if (_par.FileData == null)
                {
                    tpf = new FileStream(_par._filename, FileMode.Open, FileAccess.Read);
                }
                else
                {
                    tpf = new MemoryStream(_par.FileData);
                }

                tpf.Seek(FileOffset, SeekOrigin.Begin);
                databuff = ZipReader.BuffXOR(tpf, dataoff + (int)ComprSize + 16); // XOR the whole data block as well as the footer

                // KFreon: Dispose of stream IF it was a FileStream
                if (_par.FileData == null)
                {
                    tpf.Dispose();
                }

                // Check for correct header data and such
                ZipEntry fileentry = new ZipEntry(databuff);

                if (!fileentry.Compare(this))
                {
                    throw new InvalidDataException("File header not as expected");
                }


                // KFreon: Apparently not necessary. Some TPF's fail to load with this, but when commented out, they load fine, so...

                /*if (BitConverter.ToUInt32(databuff, (int)ComprSize + dataoff) != datadescriptormagic)
                 *  Console.WriteLine("Footer not as expected");*/

                ZipDecrypto crypto = new ZipDecrypto(this, databuff, dataoff, (int)ComprSize);

                databuff = crypto.GetBlocks();

                databuff = Deflate(databuff, 12 + dataoff, (int)ComprSize - 12);
                if (databuff.Length != UncomprSize)
                {
                    throw new InvalidDataException("Deflation resulted in incorrect file size");
                }
                CRC32 crcgen = new CRC32();

                if (crcgen.BlockChecksum(databuff, 0, (int)UncomprSize) != CRC)
                {
                    throw new InvalidDataException("Checksums don't match");
                }

                if (!Preview)
                {
                    outname = outname ?? Filename;
                    using (FileStream fs = new FileStream(outname, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(databuff, 0, (int)UncomprSize);
                    }
                    return(null);
                }
                else
                {
                    return(databuff);
                }
            }
예제 #19
0
 public KFreonZipCrypto(ZipReader.ZipEntry entry, byte[] block, int start, int count)
 {
     Blocks = DecryptData(entry, block, start, count);
 }
예제 #20
0
 public ZipEntry(ZipReader par)
 {
     _par = par;
 }