From 329589122aad3b8514ccea388cf4be6163d37f63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C5=82awomir=20=C5=9Apiewak?= Date: Sun, 18 Aug 2024 10:46:41 +0200 Subject: [PATCH] Fix cases where files with non-ascii names would fail to decrypt. --- ArcFormats/DxLib/ArcDX8.cs | 5 +---- ArcFormats/DxLib/DxKey.cs | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/ArcFormats/DxLib/ArcDX8.cs b/ArcFormats/DxLib/ArcDX8.cs index 45b46528..8daf5bfd 100644 --- a/ArcFormats/DxLib/ArcDX8.cs +++ b/ArcFormats/DxLib/ArcDX8.cs @@ -150,7 +150,7 @@ namespace GameRes.Formats.DxLib if (isencrypted) { var keyStr = Query(arcStrings.ZIPEncryptedNotice).Keyword; - key = new DxKey8(keyStr); + key = new DxKey8(keyStr,dx.CodePage); } @@ -191,9 +191,6 @@ namespace GameRes.Formats.DxLib long dec_offset = dx_ent.UnpackedSize; var key = dx_arc.Encryption.GetEntryKey(dx_ent.Name); input = new EncryptedStream(input, dec_offset, key); - if (!dx_ent.HuffmanCompressed && !dx_ent.IsPacked) - return input; - //we ruled out the case in which neither compression is applied. We still have 3 cases to go. byte[] tmpBuffer = new byte[dx_ent.Size]; input.Read(tmpBuffer, 0, tmpBuffer.Length); diff --git a/ArcFormats/DxLib/DxKey.cs b/ArcFormats/DxLib/DxKey.cs index 6fdcccff..5e5ba6b9 100644 --- a/ArcFormats/DxLib/DxKey.cs +++ b/ArcFormats/DxLib/DxKey.cs @@ -159,8 +159,10 @@ namespace GameRes.Formats.DxLib [Serializable] public class DxKey8 : DxKey { - public DxKey8(string password) : base(password ?? "DXARC") + private int codepage; + public DxKey8(string password,int codepage) : base(password ?? "DXARC") { + this.codepage = codepage; } public override byte[] GetEntryKey(string name) @@ -179,13 +181,26 @@ namespace GameRes.Formats.DxLib { keyword += "DXARC"; } - string oddString, evenString; - byte[] key = new byte[7]; - oddString = string.Concat(keyword.Where((c, i) => i % 2 == 0)); - evenString = string.Concat(keyword.Where((c, i) => (i+1) % 2 == 0)); + //first split string to bytes. Use original encoding as basis. Otherwise we would fail to decrypt that. + Encoding defEncoding = Encoding.UTF8; + Encoding tgtEncoding = Encoding.GetEncoding(codepage); + byte[] defBytes = defEncoding.GetBytes(keyword); + byte[] tgtBytes = Encoding.Convert(defEncoding, tgtEncoding, defBytes); + byte[] oddBuffer = new byte[tgtBytes.Length]; int oddCounter = 0; + byte[] evenBuffer = new byte[tgtBytes.Length]; int evenCounter = 0; + for (int i=0; i i % 2 == 0)); + evenString = string.Concat(keyword.Where((c, i) => (i+1) % 2 == 0)); + UInt32 crc_0, crc_1; + crc_0 = Crc32.Compute(Encoding.ASCII.GetBytes(oddString), 0, oddString.Length); + crc_1 = Crc32.Compute(Encoding.ASCII.GetBytes(evenString), 0, evenString.Length); */ /* using (var sha = SHA256.Create()) {