guess keys of DXA archives.

This commit is contained in:
morkt
2016-03-18 06:23:51 +04:00
parent 5bbd10789e
commit 9af7f41ef5
2 changed files with 52 additions and 5 deletions

View File

@@ -61,13 +61,15 @@ namespace GameRes.Formats.DxLib
public DxOpener () public DxOpener ()
{ {
Extensions = new string[] { "dxa", "hud", "usi", "med", "dat" }; Extensions = new string[] { "dxa", "hud", "usi", "med", "dat" };
Signatures = new uint[] { 0x19EF8ED4, 0xA9FCCEDD, 0x0AEE0FD3, 0 }; Signatures = new uint[] { 0x19EF8ED4, 0xA9FCCEDD, 0x0AEE0FD3, 0x5523F211, 0 };
} }
public static IList<byte[]> KnownKeys = new List<byte[]>(); public static IList<byte[]> KnownKeys = new List<byte[]>();
public override ArcFile TryOpen (ArcView file) public override ArcFile TryOpen (ArcView file)
{ {
if (file.MaxOffset < 0x1C)
return null;
uint signature = file.View.ReadUInt32 (0); uint signature = file.View.ReadUInt32 (0);
foreach (var key in KnownKeys) foreach (var key in KnownKeys)
{ {
@@ -79,13 +81,53 @@ namespace GameRes.Formats.DxLib
var dir = ReadIndex (file, version, key); var dir = ReadIndex (file, version, key);
if (null != dir) if (null != dir)
{ {
// move last used key to the top of the known keys list if (KnownKeys[0] != key)
KnownKeys.Remove (key); {
// move last used key to the top of the known keys list
KnownKeys.Remove (key);
KnownKeys.Insert (0, key);
}
return new DxArchive (file, this, dir, key);
}
return null;
}
}
return GuessKey (file);
}
ArcFile GuessKey (ArcView file)
{
if (file.MaxOffset > uint.MaxValue)
return null;
var key = new byte[12];
for (short version = 4; version >= 1; --version)
{
file.View.Read (0, key, 0, 12);
key[0] ^= (byte)'D';
key[1] ^= (byte)'X';
key[2] ^= (byte)version;
int base_offset = version > 3 ? 0x1C : 0x18;
key[8] ^= (byte)base_offset;
uint key0 = LittleEndian.ToUInt32 (key, 0);
uint index_offset = file.View.ReadUInt32 (12) ^ key0;
if (index_offset <= base_offset || index_offset >= file.MaxOffset)
continue;
uint index_size = (uint)(file.MaxOffset - index_offset);
if (index_size > 0xFFFFFF)
continue;
key[4] ^= (byte)index_size;
key[5] ^= (byte)(index_size >> 8);
key[6] ^= (byte)(index_size >> 16);
try
{
var dir = ReadIndex (file, version, key);
if (null != dir)
{
KnownKeys.Insert (0, key); KnownKeys.Insert (0, key);
return new DxArchive (file, this, dir, key); return new DxArchive (file, this, dir, key);
} }
break;
} }
catch { /* ignore parse errors */ }
} }
return null; return null;
} }
@@ -184,6 +226,8 @@ namespace GameRes.Formats.DxLib
FileTable = LittleEndian.ToUInt32 (header, 0x0c), FileTable = LittleEndian.ToUInt32 (header, 0x0c),
DirTable = LittleEndian.ToUInt32 (header, 0x10), DirTable = LittleEndian.ToUInt32 (header, 0x10),
}; };
if (dx.DirTable >= dx.IndexSize || dx.FileTable >= dx.IndexSize)
return null;
using (var encrypted = file.CreateStream (dx.IndexOffset, dx.IndexSize)) using (var encrypted = file.CreateStream (dx.IndexOffset, dx.IndexSize))
using (var index = new EncryptedStream (encrypted, dx.IndexOffset, key)) using (var index = new EncryptedStream (encrypted, dx.IndexOffset, key))
using (var reader = new IndexReader (dx, version, index)) using (var reader = new IndexReader (dx, version, index))

View File

@@ -34,6 +34,7 @@ Remember11<br/>
11gatsu no Arcadia<br/> 11gatsu no Arcadia<br/>
Chou Dengeki Stryker<br/> Chou Dengeki Stryker<br/>
Chou Jikuu Bakuren Monogatari ~door pi chu~<br/> Chou Jikuu Bakuren Monogatari ~door pi chu~<br/>
Eiken Kikaku<br/>
H2O -Footprints in the Sand-<br/> H2O -Footprints in the Sand-<br/>
Melty Moment<br/> Melty Moment<br/>
Traveling Stars<br/> Traveling Stars<br/>
@@ -424,6 +425,7 @@ X Change 2<br/>
X Change 2R<br/> X Change 2R<br/>
Ryoujoku Gojuusou<br/> Ryoujoku Gojuusou<br/>
Hissatsu Chikannin II<br/> Hissatsu Chikannin II<br/>
Tokumei Sentai Sirenger<br/>
Tokumei Sentai Yuzu Ranger<br/> Tokumei Sentai Yuzu Ranger<br/>
</td></tr> </td></tr>
<tr class="odd"><td>*.cwp</td><td><tt>CWDP</tt></td><td>Yes</td></tr> <tr class="odd"><td>*.cwp</td><td><tt>CWDP</tt></td><td>Yes</td></tr>
@@ -455,7 +457,7 @@ Gakuen ~Nerawareta Chitai~<br/>
Kimon Youitan<br/> Kimon Youitan<br/>
Unbalance<br/> Unbalance<br/>
</td></tr> </td></tr>
<tr class="odd"><td>*.lib<br/>*.dat</td><td><tt>LIB</tt><br/><tt>LIBP</tt><br/><tt>LIBU</tt></td><td>No</td><td rowspan="2">Malie</td><td rowspan="2"> <tr class="odd"><td>*.lib<br/>*.dat</td><td><tt>LIB</tt><br/><tt>LIBP</tt><br/><tt>LIBU</tt><span class="footnote">encrypted</span></td><td>No</td><td rowspan="2">Malie</td><td rowspan="2">
Angel Crown<br/> Angel Crown<br/>
Dies irae<br/> Dies irae<br/>
Dies irae ~Amantes amentes~<br/> Dies irae ~Amantes amentes~<br/>
@@ -577,6 +579,7 @@ Soukai no Valkyria <br/>
Ashita wa Kitto, Haremasu you ni<br/> Ashita wa Kitto, Haremasu you ni<br/>
Cross Quartz<br/> Cross Quartz<br/>
Hyakki Yakou<br/> Hyakki Yakou<br/>
Saikyou Goshujin-sama! -Mighty My Master-<br/>
</td></tr> </td></tr>
<tr class="odd"><td>*.tcd</td><td><tt>TCD3</tt></td><td>No</td><td rowspan="2">TopCat</td><td rowspan="2"> <tr class="odd"><td>*.tcd</td><td><tt>TCD3</tt></td><td>No</td><td rowspan="2">TopCat</td><td rowspan="2">
Atori no Sora to Shinchuu no Tsuki<br/> Atori no Sora to Shinchuu no Tsuki<br/>