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)); }
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)); }
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)); }
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); }