Пример #1
0
        public static RageArchiveWrapper7 Open(Stream stream, string fileName, bool leaveOpen = false)
        {
            var arch = new RageArchiveWrapper7(stream, fileName, leaveOpen);

            try
            {
                if (GTA5Constants.PC_LUT != null && GTA5Constants.PC_NG_KEYS != null)
                {
                    // calculate key...
                    var tmp1 = GTA5Hash.CalculateHash(arch.FileName);
                    var tmp2 = (tmp1 + (uint)stream.Length + (101 - 40)) % 0x65;

                    arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[tmp2]); // read...
                }
                else
                {
                    arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, null); // read...
                }

                return(arch);
            }
            catch
            {
                arch.Dispose();
                throw;
            }
        }
Пример #2
0
        /// <summary>
        /// Clears all buffers for this archive and causes any buffered data to be
        /// written to the underlying device.
        /// </summary>
        public void Flush()
        {
            long headerSize = GetHeaderSize();

            do
            {
                var  blocks          = GetBlocks();
                long maxheaderlength = ArchiveHelpers.FindSpace(blocks, blocks[0]);
                if (maxheaderlength < headerSize)
                {
                    long newpos = ArchiveHelpers.FindOffset(blocks, blocks[1].Length, 512);
                    ArchiveHelpers.MoveBytes(archive_.BaseStream, blocks[1].Offset, newpos, blocks[1].Length);
                    ((IRageArchiveFileEntry7)blocks[1].Tag).FileOffset = (uint)(newpos / 512);

                    blocks          = GetBlocks();
                    maxheaderlength = ArchiveHelpers.FindSpace(blocks, blocks[0]);
                }
                else
                {
                    break;
                }
            } while (true);



            // calculate key...
            var tmp1 = GTA5Hash.CalculateHash(FileName);
            var tmp2 = (tmp1 + (uint)archive_.BaseStream.Length + (101 - 40)) % 0x65;

            //  archive_.key_ = GTA5Crypto.key_gta5;
            archive_.WriteHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[tmp2]);
            archive_.BaseStream.Flush();
        }
Пример #3
0
        public static byte[] GetNGKey(string name, uint length)
        {
            uint hash   = GTA5Hash.CalculateHash(name);
            uint keyidx = (hash + length + (101 - 40)) % 0x65;

            return(GTA5Keys.PC_NG_KEYS[keyidx]);
        }
Пример #4
0
        public static RageArchiveWrapper7 Open(string fileName)
        {
            var finfo = new FileInfo(fileName);
            var fs    = new FileStream(fileName, FileMode.Open);
            var arch  = new RageArchiveWrapper7(fs, finfo.Name, false);

            try
            {
                if (GTA5Constants.PC_LUT != null && GTA5Constants.PC_NG_KEYS != null)
                {
                    // calculate key...
                    var tmp1 = GTA5Hash.CalculateHash(arch.FileName);
                    var tmp2 = (tmp1 + (uint)finfo.Length + (101 - 40)) % 0x65;

                    arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[tmp2]); // read...
                }
                else
                {
                    arch.archive_.ReadHeader(GTA5Constants.PC_AES_KEY, null); // read...
                }


                return(arch);
            }
            catch
            {
                fs.Dispose();
                arch.Dispose();
                throw;
            }
        }
Пример #5
0
        /// <summary>
        /// Clears all buffers for this archive and causes any buffered data to be
        /// written to the underlying device.
        /// </summary>
        public void Flush()
        {
            long headerSize = GetHeaderSize();

            for (;;)
            {
                List <DataBlock> blocks = GetBlocks();

                long num = ArchiveHelpers.FindSpace(blocks, blocks[0]);

                if (num >= headerSize)
                {
                    break;
                }

                long num2 = ArchiveHelpers.FindOffset(blocks, blocks[1].Length, 512);

                ArchiveHelpers.MoveBytes(archive_.BaseStream, blocks[1].Offset, num2, blocks[1].Length);

                ((IRageArchiveFileEntry7)blocks[1].Tag).FileOffset = (uint)(num2 / 512);
                blocks = this.GetBlocks();
                num    = ArchiveHelpers.FindSpace(blocks, blocks[0]);
            }

            uint num3 = GTA5Hash.CalculateHash(FileName);
            uint num4 = (num3 + (uint)archive_.BaseStream.Length + 0x3D) % 0x65;

            archive_.WriteHeader(GTA5Constants.PC_AES_KEY, GTA5Constants.PC_NG_KEYS[(int)num4]);
            archive_.BaseStream.Flush();
        }
Пример #6
0
        public static HashSet <string> GetAllStringsFromAllXmls(string gameDirectoryName)
        {
            var xmlStrings = new HashSet <string>();

            ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) =>
            {
                if (file.Name.EndsWith(".meta", StringComparison.OrdinalIgnoreCase) ||
                    file.Name.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
                {
                    var fileStream = new MemoryStream();
                    file.Export(fileStream);

                    var buf             = new byte[fileStream.Length];
                    fileStream.Position = 0;
                    fileStream.Read(buf, 0, buf.Length);

                    if (file.IsEncrypted)
                    {
                        if (encryption == RageArchiveEncryption7.AES)
                        {
                            buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY);
                        }
                        else
                        {
                            var qq = GTA5Hash.CalculateHash(file.Name);
                            var gg = (qq + (uint)file.UncompressedSize + (101 - 40)) % 0x65;
                            buf    = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[gg]);
                        }
                    }

                    if (file.IsCompressed)
                    {
                        var def    = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress);
                        var bufnew = new byte[file.UncompressedSize];
                        def.Read(bufnew, 0, (int)file.UncompressedSize);
                        buf = bufnew;
                    }

                    var cleanedStream = new MemoryStream(buf);
                    foreach (string xmlString in GetAllStringsFromXml(cleanedStream))
                    {
                        xmlStrings.Add(xmlString);
                    }

                    Console.WriteLine(file.Name);
                }
            });

            return(xmlStrings);
        }
        private Stream GetExportStream()
        {
            var binaryStream = GetStream();

            if (IsEncrypted)
            {
                var qq = GTA5Hash.CalculateHash(Name);
                var gg = (qq + (uint)UncompressedSize + (101 - 40)) % 0x65;
                binaryStream = new GTA5DecryptStream(binaryStream, GTA5Constants.PC_NG_KEYS[gg]);
            }

            if (IsCompressed)
            {
                binaryStream = new DeflateStream(binaryStream, CompressionMode.Decompress);
            }

            return(binaryStream);
        }
Пример #8
0
        /// <summary>
        /// Exports a file.
        /// </summary>
        public void Export(IArchiveFile file, string fileName)
        {
            if (file is IArchiveBinaryFile)
            {
                var binFile = (IArchiveBinaryFile)file;

                // export
                var ms = new MemoryStream();
                file.Export(ms);
                ms.Position = 0;

                var buf = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(buf, 0, buf.Length);

                // decrypt...
                if (binFile.IsEncrypted)
                {
                    var qq = GTA5Hash.CalculateHash(binFile.Name);
                    var gg = (qq + (uint)binFile.UncompressedSize + (101 - 40)) % 0x65;

                    // TODO: if archive encrypted with AES, use AES key...

                    buf = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[gg]);
                }

                // decompress...
                if (binFile.IsCompressed)
                {
                    var def    = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress);
                    var bufnew = new byte[binFile.UncompressedSize];
                    def.Read(bufnew, 0, (int)binFile.UncompressedSize);
                    buf = bufnew;
                }

                File.WriteAllBytes(fileName, buf);
            }
            else
            {
                file.Export(fileName);
            }
        }
Пример #9
0
        public static HashSet <int> GetAllHashesFromPsoMetas(string gameDirectoryName)
        {
            var hashes = new HashSet <int>();

            ArchiveUtilities.ForEachBinaryFile(gameDirectoryName, (fullFileName, file, encryption) =>
            {
                if (file.Name.EndsWith(".ymf") || file.Name.EndsWith(".ymt"))
                {
                    var stream = new MemoryStream();
                    file.Export(stream);

                    var buf         = new byte[stream.Length];
                    stream.Position = 0;
                    stream.Read(buf, 0, buf.Length);

                    if (file.IsEncrypted)
                    {
                        if (encryption == RageArchiveEncryption7.AES)
                        {
                            buf = AesEncryption.DecryptData(buf, GTA5Constants.PC_AES_KEY);
                        }
                        else
                        {
                            var qq = GTA5Hash.CalculateHash(file.Name);
                            var gg = (qq + (uint)file.UncompressedSize + (101 - 40)) % 0x65;
                            buf    = GTA5Crypto.Decrypt(buf, GTA5Constants.PC_NG_KEYS[gg]);
                        }
                    }

                    if (file.IsCompressed)
                    {
                        var def    = new DeflateStream(new MemoryStream(buf), CompressionMode.Decompress);
                        var bufnew = new byte[file.UncompressedSize];
                        def.Read(bufnew, 0, (int)file.UncompressedSize);
                        buf = bufnew;
                    }

                    var cleanStream = new MemoryStream(buf);
                    if (PsoFile.IsPSO(cleanStream))
                    {
                        PsoFile pso = new PsoFile();
                        pso.Load(cleanStream);

                        foreach (var info in pso.DefinitionSection.EntriesIdx)
                        {
                            hashes.Add(info.NameHash);
                        }
                        foreach (var info in pso.DefinitionSection.Entries)
                        {
                            if (info is PsoStructureInfo)
                            {
                                var structureInfo = (PsoStructureInfo)info;
                                foreach (var entryInfo in structureInfo.Entries)
                                {
                                    hashes.Add(entryInfo.EntryNameHash);
                                }
                            }

                            if (info is PsoEnumInfo)
                            {
                                var enumInfo = (PsoEnumInfo)info;
                                foreach (var entryInfo in enumInfo.Entries)
                                {
                                    hashes.Add(entryInfo.EntryNameHash);
                                }
                            }
                        }

                        Console.WriteLine(file.Name);
                    }
                }
            });
            return(hashes);
        }