From b6ebb7d45189cd98adf34315a7c53321de3ab24f Mon Sep 17 00:00:00 2001 From: morkt Date: Thu, 7 Sep 2023 12:02:19 +0400 Subject: [PATCH] (CSAF): support different archive keys. --- ArcFormats/FamilyAdvSystem/ArcCSAF.cs | 31 +++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/ArcFormats/FamilyAdvSystem/ArcCSAF.cs b/ArcFormats/FamilyAdvSystem/ArcCSAF.cs index fefd232a..1af19564 100644 --- a/ArcFormats/FamilyAdvSystem/ArcCSAF.cs +++ b/ArcFormats/FamilyAdvSystem/ArcCSAF.cs @@ -2,7 +2,7 @@ //! \date 2019 Jan 01 //! \brief Family Adv System resource archive. // -// Copyright (C) 2019 by morkt +// Copyright (C) 2019-2023 by morkt // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to @@ -34,6 +34,11 @@ using GameRes.Utility; namespace GameRes.Formats.FamilyAdvSystem { + [Serializable] + public class FamilyAdvScheme : ResourceScheme + { + public IDictionary KnownKeys; + } [Export(typeof(ArchiveFormat))] public class CsafOpener : ArchiveFormat @@ -70,8 +75,9 @@ namespace GameRes.Formats.FamilyAdvSystem { if (is_encrypted) { + var key = QueryEncryptionKey (file); file.View.Read (0x20, index, 0, index_size); - enc = new CsafEncryption (DefaultKey, DefaultIV); + enc = new CsafEncryption (key, DefaultIV); using (var decryptor = enc.CreateDecryptor (0)) using (var enc_names = file.CreateStream (0x20 + index_size, names_size)) using (var dec_names = new InputCryptoStream (enc_names, decryptor)) @@ -136,6 +142,27 @@ namespace GameRes.Formats.FamilyAdvSystem var input = new CsafStream (carc); return new StreamRegion (input, entry.Offset, entry.Size); } + + internal string QueryEncryptionKey (ArcView file) + { + var title = FormatCatalog.Instance.LookupGame (file.Name); + if (string.IsNullOrEmpty (title)) + return DefaultKey; + string key; + if (!KnownKeys.TryGetValue (title, out key)) + return DefaultKey; + return key; + } + + FamilyAdvScheme DefaultScheme = new FamilyAdvScheme { KnownKeys = new Dictionary() }; + + internal IDictionary KnownKeys { get { return DefaultScheme.KnownKeys; } } + + public override ResourceScheme Scheme + { + get { return DefaultScheme; } + set { DefaultScheme = (FamilyAdvScheme)value; } + } } internal class CsafEncryption : IDisposable