Пример #1
0
        private static MemoryStream DecryptBhdFile(string filePath, GameVersion version)
        {
            string fileDirectory = Path.GetDirectoryName(filePath) ?? string.Empty;
            string fileName      = Path.GetFileName(filePath) ?? string.Empty;
            string key           = null;

            switch (version)
            {
            case GameVersion.DarkSouls2:
                string keyFileName = Regex.Replace(fileName, @"Ebl\.bhd$", "KeyCode.pem", RegexOptions.IgnoreCase);
                string keyFilePath = Path.Combine(fileDirectory, keyFileName);
                if (File.Exists(keyFilePath))
                {
                    key = File.ReadAllText(keyFilePath);
                }
                break;

            case GameVersion.DarkSouls3:
                DecryptionKeys.TryGetRsaFileKey(fileName, out key);
                break;
            }

            if (key == null)
            {
                throw new ApplicationException($"Missing decryption key for file \'{fileName}\'");
            }

            return(CryptographyUtility.DecryptRsa(filePath, key));
        }
Пример #2
0
        private static MemoryStream DecryptBhdFile(string filePath)
        {
            string fileName = Path.GetFileName(filePath);
            string key;

            if (!DecryptionKeys.TryGetRsaFileKey(fileName, out key))
            {
                throw new ApplicationException($"Missing decryption key for file \'{fileName}\'");
            }

            return(CryptographyUtility.DecryptRsa(filePath, key));
        }
Пример #3
0
        private static MemoryStream DecryptBhdFile(string filePath, GameVersion version)
        {
            string fileDirectory = Path.GetDirectoryName(filePath) ?? string.Empty;
            string fileName      = Path.GetFileName(filePath) ?? string.Empty;
            string key           = null;

            // hack: bhd5 may already be decrypted!
            FileStream   fs = File.Open(filePath, FileMode.Open);
            MemoryStream ms = new MemoryStream();

            fs.CopyTo(ms);
            fs.Close();
            ms.Seek(0, SeekOrigin.Begin);
            string bhd5_sig;

            if (TryGetAsciiSignature(ms, 4, out bhd5_sig))
            {
                if (bhd5_sig == "BHD5")
                {
                    return(ms);
                }
            }

            switch (version)
            {
            case GameVersion.DarkSouls2:
                string keyFileName = Regex.Replace(fileName, @"Ebl\.bhd$", "KeyCode.pem", RegexOptions.IgnoreCase);
                string keyFilePath = Path.Combine(fileDirectory, keyFileName);
                if (File.Exists(keyFilePath))
                {
                    key = File.ReadAllText(keyFilePath);
                }
                break;

            case GameVersion.DarkSouls3:
                DecryptionKeys.TryGetRsaFileKey(fileName, out key);
                break;
            }

            if (key == null)
            {
                throw new ApplicationException($"Missing decryption key for file \'{fileName}\'");
            }

            return(CryptographyUtility.DecryptRsa(filePath, key));
        }
Пример #4
0
        private bool unpackBDT(string name, string key, Progress progress, bool required)
        {
            if (stop)
            {
                return(true);
            }

            string bhdPath = gameDir + "\\" + name + ".bhd";
            string bdtPath = gameDir + "\\" + name + ".bdt";

            if (!(File.Exists(bhdPath) && File.Exists(bdtPath)))
            {
                if (required)
                {
                    Error = "File not found:\n" + (File.Exists(bhdPath) ? bdtPath : bhdPath);
                    return(false);
                }
                else
                {
                    return(true);
                }
            }
            Status = "Unpacking " + name + "...";

            Bhd5File bhd;

            try
            {
                using (MemoryStream bhdStream = CryptographyUtility.DecryptRsa(bhdPath, key))
                {
                    bhd = Bhd5File.Read(bhdStream, GameVersion.DarkSouls3);
                }
            }
            catch (Exception ex)
            {
                Error = $"Failed to open BHD:\n{bhdPath}\n\n{ex}";
                return(false);
            }

            int fileCount = 0;

            foreach (Bhd5Bucket bucket in bhd.GetBuckets())
            {
                fileCount += bucket.GetEntries().Count();
            }
            progress.Value = 0;
            progress.Max   = fileCount;

            try
            {
                using (Bdt5FileStream bdtStream = Bdt5FileStream.OpenFile(bdtPath, FileMode.Open, FileAccess.Read))
                {
                    foreach (Bhd5Bucket bucket in bhd.GetBuckets())
                    {
                        foreach (Bhd5BucketEntry entry in bucket.GetEntries())
                        {
                            if (stop)
                            {
                                return(true);
                            }

                            if (entry.FileSize == 0)
                            {
                                MemoryStream header = bdtStream.Read(entry.FileOffset, 48);
                                if (entry.IsEncrypted)
                                {
                                    MemoryStream disposer = header;
                                    header = CryptographyUtility.DecryptAesEcb(header, entry.AesKey.Key);
                                    disposer.Dispose();
                                }

                                byte[] signatureBytes = new byte[4];
                                header.Read(signatureBytes, 0, 4);
                                string signature = ASCII.GetString(signatureBytes);
                                if (signature != DcxFile.DcxSignature)
                                {
                                    Error = "Zero-length entry is not DCX in BHD:\n" + bhdPath;
                                    return(false);
                                }

                                header.Position = 0;
                                entry.FileSize  = DcxFile.DcxSize + DcxFile.ReadCompressedSize(header);
                                header.Dispose();
                            }

                            MemoryStream data;
                            if (entry.IsEncrypted)
                            {
                                data = bdtStream.Read(entry.FileOffset, entry.PaddedFileSize);
                                CryptographyUtility.DecryptAesEcb(data, entry.AesKey.Key, entry.AesKey.Ranges);
                                data.Position = 0;
                                data.SetLength(entry.FileSize);
                            }
                            else
                            {
                                data = bdtStream.Read(entry.FileOffset, entry.FileSize);
                            }

                            string path;
                            if (ArchiveDictionary.GetPath(entry.FileNameHash, out path))
                            {
                                path = gameDir + path.Replace('/', '\\');
                            }
                            else
                            {
                                path = $"{gameDir}\\_unknown\\{name}_{entry.FileNameHash:D10}";
                            }

                            try
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(path));
                                File.WriteAllBytes(path, data.ToArray());
                            }
                            catch (Exception ex)
                            {
                                Error = $"Failed to write file:\n{path}\n\n{ex}";
                                return(false);
                            }

                            data.Dispose();
                            progress.Value++;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Error = $"Failed to unpack BDT:\n{bdtPath}\n\n{ex}";
                return(false);
            }

            return(true);
        }