예제 #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 static void UnpackBdtFile(Options options)
        {
            FileNameDictionary dictionary = FileNameDictionary.OpenFromFile(options.InputGameVersion);
            string             fileNameWithoutExtension = Path.GetFileName(options.InputPath).Replace("Ebl.bdt", "").Replace(".bdt", "");
            string             archiveName = fileNameWithoutExtension.ToLower();

            using (Bdt5FileStream bdtStream = Bdt5FileStream.OpenFile(options.InputPath, FileMode.Open, FileAccess.Read))
            {
                Bhd5File bhdFile = Bhd5File.Read(
                    inputStream: DecryptBhdFile(
                        filePath: Path.ChangeExtension(options.InputPath, "bhd"),
                        version: options.InputGameVersion),
                    version: options.InputGameVersion
                    );
                foreach (var bucket in bhdFile.GetBuckets())
                {
                    foreach (var entry in bucket.GetEntries())
                    {
                        MemoryStream data;
                        if (entry.FileSize == 0)
                        {
                            long fileSize;
                            if (!TryReadFileSize(entry, bdtStream, out fileSize))
                            {
                                Console.WriteLine($"Unable to determine the length of file '{entry.FileNameHash:D10}'");
                                continue;
                            }

                            entry.FileSize = fileSize;
                        }

                        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 fileName;
                        string dataExtension = GetDataExtension(data);
                        bool   fileNameFound = dictionary.TryGetFileName(entry.FileNameHash, archiveName, out fileName);
                        if (!fileNameFound)
                        {
                            fileNameFound = dictionary.TryGetFileName(entry.FileNameHash, archiveName, dataExtension, out fileName);
                        }

                        string extension;
                        if (fileNameFound)
                        {
                            extension = Path.GetExtension(fileName);

                            if (dataExtension == ".dcx" && extension != ".dcx")
                            {
                                extension = ".dcx";
                                fileName += ".dcx";
                            }
                        }
                        else
                        {
                            extension = dataExtension;
                            fileName  = $"{entry.FileNameHash:D10}_{fileNameWithoutExtension}{extension}";
                        }

                        if (extension == ".enc")
                        {
                            byte[] decryptionKey;
                            if (DecryptionKeys.TryGetAesFileKey(Path.GetFileName(fileName), out decryptionKey))
                            {
                                EncFile encFile = EncFile.ReadEncFile(data, decryptionKey);
                                data = encFile.Data;

                                fileName  = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName));
                                extension = Path.GetExtension(fileName);
                            }
                            else
                            {
                                Debug.WriteLine($"No decryption key for file \'{fileName}\' found.");
                            }
                        }

                        if (extension == ".dcx")
                        {
                            DcxFile dcxFile = DcxFile.Read(data);
                            data = new MemoryStream(dcxFile.Decompress());

                            fileName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName));

                            if (fileNameFound)
                            {
                                extension = Path.GetExtension(fileName);
                            }
                            else
                            {
                                extension = GetDataExtension(data);
                                fileName += extension;
                            }
                        }

                        if (extension == ".bnd")
                        {
                            UnpackBnd3File(data, options.OutputPath);
                            continue; // don't actually unpack bnds
                        }

                        Debug.WriteLine(
                            "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}",
                            fileNameWithoutExtension,
                            fileName,
                            extension,
                            entry.FileNameHash,
                            entry.FileOffset,
                            entry.FileSize,
                            entry.PaddedFileSize,
                            entry.IsEncrypted,
                            fileNameFound);

                        string newFileNamePath = Path.Combine(options.OutputPath, fileName);
                        Directory.CreateDirectory(Path.GetDirectoryName(newFileNamePath));
                        File.WriteAllBytes(newFileNamePath, data.ToArray());
                    }
                }
            }
        }