Compare commits

...

19 Commits

Author SHA1 Message Date
morkt
0b8eb1f9d4 implemented Will co. archives creation. 2014-11-01 02:14:51 +04:00
morkt
56d2a45d94 implemented Will co. engine resources. 2014-10-31 18:50:43 +04:00
morkt
6736819db1 cosmetic changes. 2014-10-31 18:47:37 +04:00
morkt
6aeb3ea27e automatically update assembly build/revision number. 2014-10-31 18:47:02 +04:00
morkt
1faea63667 cosmetic changes. 2014-09-12 16:04:38 +04:00
morkt
82b1fc0603 (ArcFile.OverwriteNotify): new event.
preliminary support for extracted file overwrite notification.
2014-09-12 16:04:18 +04:00
morkt
ae559f34a6 (ArchiveFormat.CopyEntry): new virtual method.
the idea is to allow implementations to give extracted file a name
different from the one it stored within archive.
2014-09-12 16:03:30 +04:00
morkt
f02cc382a1 BGI/Ethornell engine archive implementation. 2014-09-12 15:59:56 +04:00
morkt
58018d3c67 (ArcStream): added constructors from ArcView.Frame 2014-09-12 15:58:18 +04:00
morkt
12df1dcdfd (GetScheme): fixed potential bug when looking up unknown encryption scheme. 2014-09-09 01:04:27 +04:00
morkt
1c5008d799 fixed empty 'recent files' menu. 2014-09-08 12:15:13 +04:00
morkt
58f8b4845d incremented version number. 2014-09-08 11:54:39 +04:00
morkt
a0162b4bbc Cx encryption bytecode generation fix. 2014-09-08 11:27:24 +04:00
morkt
12d8236d3d fixed Imouto Style encryption constants. 2014-09-08 08:29:05 +04:00
morkt
a267a8dd1f implemented KiriKiri "Cx" encryption scheme. 2014-09-08 08:02:07 +04:00
morkt
aea3a47ccc incremented version number. 2014-09-08 07:37:15 +04:00
morkt
5d4696de4c cosmetic changes. 2014-09-08 07:36:20 +04:00
morkt
c5982da278 Revert "cosmetic changes."
This reverts commit 06e651d43b.
2014-09-07 21:30:47 +04:00
morkt
06e651d43b cosmetic changes. 2014-08-31 18:49:42 +04:00
30 changed files with 1982 additions and 54 deletions

View File

@@ -294,9 +294,12 @@ namespace GameRes.Formats
return packed_size;
}
static Lazy<GrpFormat> s_grp_format = new Lazy<GrpFormat> (() =>
FormatCatalog.Instance.ImageFormats.OfType<GrpFormat>().FirstOrDefault());
uint WriteImageEntry (PackedEntry entry, Stream input, Stream output)
{
var grp = FormatCatalog.Instance.ImageFormats.OfType<GrpFormat>().FirstOrDefault();
var grp = s_grp_format.Value;
if (null == grp) // probably never happens
throw new FileFormatException ("GRP image encoder not available");
bool is_grp = grp.Signature == FormatCatalog.ReadSignature (input);

310
ArcFormats/ArcBGI.cs Normal file
View File

@@ -0,0 +1,310 @@
//! \file ArcBGI.cs
//! \date Tue Sep 09 09:29:12 2014
//! \brief BGI/Ethornell engine archive implementation.
//
// Copyright (C) 2014 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
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using GameRes.Utility;
namespace GameRes.Formats.BGI
{
[Export(typeof(ArchiveFormat))]
public class ArcOpener : ArchiveFormat
{
public override string Tag { get { return "BGI"; } }
public override string Description { get { return "BGI/Ethornell engine resource archive"; } }
public override uint Signature { get { return 0x6b636150; } } // "Pack"
public override bool IsHierarchic { get { return false; } }
public override bool CanCreate { get { return false; } }
public ArcOpener ()
{
Extensions = new string[] { "arc" };
}
public override ArcFile TryOpen (ArcView file)
{
if (!file.View.AsciiEqual (4, "File "))
return null;
uint count = file.View.ReadUInt32 (12);
if (count > 0xfffff)
return null;
uint index_size = 0x20 * count;
if (index_size > file.View.Reserve (0x10, index_size))
return null;
var dir = new List<Entry> ((int)count);
long index_offset = 0x10;
long base_offset = index_offset + index_size;
for (uint i = 0; i < count; ++i)
{
string name = file.View.ReadString (index_offset, 0x10);
var entry = FormatCatalog.Instance.CreateEntry (name);
entry.Offset = base_offset + file.View.ReadUInt32 (index_offset+0x10);
entry.Size = file.View.ReadUInt32 (index_offset+0x14);
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
index_offset += 0x20;
}
return new ArcFile (file, this, dir);
}
public override Stream OpenEntry (ArcFile arc, Entry entry)
{
var entry_offset = entry.Offset;
var input = new ArcView.Frame (arc.File, entry_offset, entry.Size);
try
{
if (entry.Size > 0x220 && input.AsciiEqual (entry_offset, "DSC FORMAT 1.00\0"))
{
using (var decoder = new DscDecoder (input))
{
decoder.Unpack();
byte[] data = decoder.Output;
if (data.Length > 0x40)
{
uint data_offset = LittleEndian.ToUInt32 (data, 0);
if (data_offset < data.Length-4 && 0x20207762 == LittleEndian.ToUInt32 (data, 4))
{
if (0x5367674f == LittleEndian.ToUInt32 (data, (int)data_offset)) // 'OggS'
{
return new MemoryStream (data, (int)data_offset, data.Length-(int)data_offset, false);
}
}
}
return new MemoryStream (data, false);
}
}
if (entry.Size > 0x40)
{
uint data_offset = input.ReadUInt32 (entry_offset);
if (data_offset < entry.Size-4 && 0x20207762 == input.ReadUInt32 (entry_offset+4))
{
if (0x5367674f == input.ReadUInt32 (entry_offset+data_offset)) // 'OggS'
{
return new ArcView.ArcStream (input, entry_offset+data_offset, entry.Size-data_offset);
}
}
}
return new ArcView.ArcStream (input);
}
catch
{
input.Dispose();
throw;
}
}
}
internal sealed class DscDecoder : IDisposable
{
private Stream m_input;
private byte[] m_output;
private uint m_key;
private uint m_dst_size;
private uint m_dec_count;
private uint m_magic;
public byte[] Output { get { return m_output; } }
public DscDecoder (ArcView.Frame input)
{
m_magic = (uint)input.ReadUInt16 (input.Offset) << 16;
m_key = input.ReadUInt32 (input.Offset+0x10);
m_dst_size = input.ReadUInt32 (input.Offset+0x14);
m_dec_count = input.ReadUInt32 (input.Offset+0x18);
m_input = new ArcView.ArcStream (input, input.Offset+0x20, input.Reserved-0x20);
m_output = new byte[m_dst_size];
}
struct HuffmanCode : IComparable<HuffmanCode>
{
public ushort Code;
public ushort Depth;
public int CompareTo (HuffmanCode other)
{
int cmp = (int)Depth - (int)other.Depth;
if (0 == cmp)
cmp = (int)Code - (int)other.Code;
return cmp;
}
}
class HuffmanNode
{
public bool IsParent;
public uint Code;
public uint LeftChildIndex;
public uint RightChildIndex;
}
public void Unpack ()
{
HuffmanCode[] hcodes = new HuffmanCode[512];
HuffmanNode[] hnodes = new HuffmanNode[1023];
int leaf_node_count = 0;
for (ushort i = 0; i < 512; i++)
{
int src = m_input.ReadByte();
if (-1 == src)
throw new EndOfStreamException ("Incomplete compressed stream");
byte depth = (byte)(src - UpdateKey());
if (0 != depth)
{
hcodes[leaf_node_count].Depth = depth;
hcodes[leaf_node_count].Code = i;
leaf_node_count++;
}
}
Array.Sort (hcodes, 0, leaf_node_count);
CreateHuffmanTree (hnodes, hcodes, leaf_node_count);
HuffmanDecompress (hnodes, m_dec_count);
}
void CreateHuffmanTree (HuffmanNode[] hnodes, HuffmanCode[] hcode, int node_count)
{
uint[,] nodes_index = new uint[2,512];
uint next_node_index = 1;
int depth_nodes = 1;
uint depth = 0;
int switch_flag = 0;
nodes_index[0,0] = 0;
for (int n = 0; n < node_count; )
{
int huffman_nodes_index = switch_flag;
switch_flag ^= 1;
int child_index = switch_flag;
int depth_existed_nodes = 0;
while (hcode[n].Depth == depth)
{
var node = new HuffmanNode { IsParent = false, Code = hcode[n++].Code };
hnodes[nodes_index[huffman_nodes_index, depth_existed_nodes]] = node;
depth_existed_nodes++;
}
int depth_nodes_to_create = depth_nodes - depth_existed_nodes;
for (int i = 0; i < depth_nodes_to_create; i++)
{
var node = new HuffmanNode { IsParent = true };
nodes_index[child_index, i * 2] = node.LeftChildIndex = next_node_index++;
nodes_index[child_index, i * 2 + 1] = node.RightChildIndex = next_node_index++;
hnodes[nodes_index[huffman_nodes_index, depth_existed_nodes+i]] = node;
}
depth++;
depth_nodes = depth_nodes_to_create * 2;
}
}
int m_bits = 0;
bool GetNextBit ()
{
bool carry = 0 != (m_bits & 0x80);
m_bits <<= 1;
if (0 == (m_bits & 0xff))
{
m_bits = m_input.ReadByte();
if (-1 == m_bits)
throw new EndOfStreamException ("Invalid compressed stream");
carry = 0 != (m_bits & 0x80);
m_bits = (m_bits << 1) | 1;
}
return carry;
}
bool GetBits (int count, out int bits)
{
bits = 0;
for (int i = 0; i < count; ++i)
{
bits <<= 1;
bits |= GetNextBit() ? 1 : 0;
}
return true;
}
uint HuffmanDecompress (HuffmanNode[] hnodes, uint dec_count)
{
uint dst_ptr = 0;
for (uint k = 0; k < dec_count; k++)
{
uint node_index = 0;
do
{
if (!GetNextBit())
node_index = hnodes[node_index].LeftChildIndex;
else
node_index = hnodes[node_index].RightChildIndex;
}
while (hnodes[node_index].IsParent);
uint code = hnodes[node_index].Code;
if (code >= 256)
{
int win_pos;
if (!GetBits (12, out win_pos))
break;
uint copy_bytes = (code & 0xff) + 2;
win_pos += 2;
for (uint i = 0; i < copy_bytes; i++)
{
m_output[dst_ptr] = m_output[dst_ptr - win_pos];
dst_ptr++;
}
} else
m_output[dst_ptr++] = (byte)code;
}
return dst_ptr;
}
byte UpdateKey ()
{
uint v0 = 20021 * (m_key & 0xffff);
uint v1 = m_magic | (m_key >> 16);
v1 = v1 * 20021 + m_key * 346;
v1 = (v1 + (v0 >> 16)) & 0xffff;
m_key = (v1 << 16) + (v0 & 0xffff) + 1;
return (byte)v1;
}
#region IDisposable Members
public void Dispose ()
{
if (null != m_input)
{
m_input.Dispose();
m_input = null;
}
GC.SuppressFinalize (this);
}
#endregion
}
}

View File

@@ -57,6 +57,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="ArcAMI.cs" />
<Compile Include="ArcBGI.cs" />
<Compile Include="ArcDRS.cs" />
<Compile Include="ArcINT.cs" />
<Compile Include="ArcKogado.cs" />
@@ -66,6 +67,7 @@
<Compile Include="ArcPD.cs" />
<Compile Include="ArcRPA.cs" />
<Compile Include="ArcSteinsGate.cs" />
<Compile Include="ArcWILL.cs" />
<Compile Include="ArcXFL.cs" />
<Compile Include="ArcXP3.cs" />
<Compile Include="ArcYPF.cs" />
@@ -91,6 +93,9 @@
<Compile Include="CreateSGWidget.xaml.cs">
<DependentUpon>CreateSGWidget.xaml</DependentUpon>
</Compile>
<Compile Include="CreateWARCWidget.xaml.cs">
<DependentUpon>CreateWARCWidget.xaml</DependentUpon>
</Compile>
<Compile Include="CreateXP3Widget.xaml.cs">
<DependentUpon>CreateXP3Widget.xaml</DependentUpon>
</Compile>
@@ -102,6 +107,8 @@
<Compile Include="ImageRCT.cs" />
<Compile Include="ImageTLG.cs" />
<Compile Include="ImageWCG.cs" />
<Compile Include="ImageWIP.cs" />
<Compile Include="KiriKiriCx.cs" />
<Compile Include="KogadoCocotte.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
@@ -180,6 +187,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="CreateWARCWidget.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="CreateXP3Widget.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -213,6 +224,9 @@
<EmbeddedResource Include="Strings\arcStrings.ru-RU.resx" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>perl "$(SolutionDir)inc-revision.pl" "$(ProjectPath)" $(ConfigurationName)</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -174,12 +174,15 @@ namespace GameRes.Formats.Kogado
try
{
string name = Path.GetFileNameWithoutExtension (entry.Name);
string ext = Path.GetExtension (entry.Name).TrimStart ('.').ToLowerInvariant();
string ext = Path.GetExtension (entry.Name);
byte[] name_buf = new byte[0x15];
byte[] ext_buf = new byte[3];
encoding.GetBytes (name, 0, name.Length, name_buf, 0);
if (!string.IsNullOrEmpty (ext))
{
ext = ext.TrimStart ('.').ToLowerInvariant();
encoding.GetBytes (ext, 0, ext.Length, ext_buf, 0);
}
var out_entry = new OutputEntry
{
Name = entry.Name,

View File

@@ -594,9 +594,9 @@ namespace GameRes.Formats.NitroPlus
private bool m_read_mode;
private long m_base_pos;
public override bool CanRead { get { return m_read_mode; } }
public override bool CanRead { get { return m_read_mode && m_stream.CanRead; } }
public override bool CanSeek { get { return m_stream.CanSeek; } }
public override bool CanWrite { get { return !m_read_mode; } }
public override bool CanWrite { get { return !m_read_mode && m_stream.CanWrite; } }
public override long Length { get { return m_stream.Length - m_base_pos; } }
public override long Position
{

View File

@@ -176,9 +176,7 @@ namespace GameRes.Formats.ONScripter
break;
if (name_buffer.Length == name_len)
{
byte[] new_buffer = new byte[checked(name_len/2*3)];
Array.Copy (name_buffer, new_buffer, name_len);
name_buffer = new_buffer;
Array.Resize (ref name_buffer, checked(name_len/2*3));
}
name_buffer[name_len] = b;
}

226
ArcFormats/ArcWILL.cs Normal file
View File

@@ -0,0 +1,226 @@
//! \file ArcWILL.cs
//! \date Fri Oct 31 13:37:11 2014
//! \brief ARC archive format implementation.
//
// Copyright (C) 2014 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
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using GameRes.Formats.Properties;
using GameRes.Formats.Strings;
namespace GameRes.Formats.Will
{
internal class ExtRecord
{
public string Extension;
public int FileCount;
public uint DirOffset;
}
public class ArcOptions : ResourceOptions
{
public int NameLength { get; set; }
}
[Export(typeof(ArchiveFormat))]
public class ArcOpener : ArchiveFormat
{
public override string Tag { get { return "WARC"; } }
public override string Description { get { return "Will Co. game engine resource archive"; } }
public override uint Signature { get { return 0; } }
public override bool IsHierarchic { get { return false; } }
public override bool CanCreate { get { return true; } }
ArcOpener ()
{
Extensions = new string[] { "arc" };
}
public override ArcFile TryOpen (ArcView file)
{
int ext_count = file.View.ReadInt32 (0);
if (ext_count <= 0 || ext_count > 0xff)
return null;
uint dir_offset = 4;
var ext_list = new List<ExtRecord> (ext_count);
for (int i = 0; i < ext_count; ++i)
{
string ext = file.View.ReadString (dir_offset, 4).ToLowerInvariant();
int count = file.View.ReadInt32 (dir_offset+4);
uint offset = file.View.ReadUInt32 (dir_offset+8);
if (count <= 0 || count > 0xffff || offset <= dir_offset || offset > file.MaxOffset)
return null;
ext_list.Add (new ExtRecord { Extension = ext, FileCount = count, DirOffset = offset });
dir_offset += 12;
}
var dir = ReadFileList (file, ext_list, 9);
if (null == dir)
dir = ReadFileList (file, ext_list, 13);
if (null == dir)
return null;
return new ArcFile (file, this, dir);
}
List<Entry> ReadFileList (ArcView file, IEnumerable<ExtRecord> ext_list, uint name_size)
{
var dir = new List<Entry>();
foreach (var ext in ext_list)
{
dir.Capacity = dir.Count + ext.FileCount;
uint dir_offset = ext.DirOffset;
for (int i = 0; i < ext.FileCount; ++i)
{
string name = file.View.ReadString (dir_offset, name_size);
if (string.IsNullOrEmpty (name))
return null;
name = name.ToLowerInvariant()+'.'+ext.Extension;
var entry = FormatCatalog.Instance.CreateEntry (name);
entry.Size = file.View.ReadUInt32 (dir_offset+name_size);
entry.Offset = file.View.ReadUInt32 (dir_offset+name_size+4);
if (!entry.CheckPlacement (file.MaxOffset))
return null;
dir.Add (entry);
dir_offset += name_size+8;
}
}
return dir;
}
public override ResourceOptions GetDefaultOptions ()
{
return new ArcOptions { NameLength = Settings.Default.WARCNameLength };
}
public override object GetCreationWidget ()
{
return new GUI.CreateWARCWidget();
}
internal class ArcEntry : Entry
{
public byte[] RawName;
}
internal class ArcDirectory
{
public byte[] Extension;
public uint DirOffset;
public List<ArcEntry> Files;
}
public override void Create (Stream output, IEnumerable<Entry> list, ResourceOptions options,
EntryCallback callback)
{
var arc_options = GetOptions<ArcOptions> (options);
var encoding = Encodings.cp932.WithFatalFallback();
int file_count = 0;
var file_table = new SortedDictionary<string, ArcDirectory>();
foreach (var entry in list)
{
string ext = Path.GetExtension (entry.Name).TrimStart ('.').ToUpperInvariant();
if (string.IsNullOrEmpty (ext))
throw new InvalidFileName (entry.Name, arcStrings.MsgNoExtension);
if (ext.Length > 3)
throw new InvalidFileName (entry.Name, arcStrings.MsgExtensionTooLong);
string name = Path.GetFileNameWithoutExtension (entry.Name).ToUpperInvariant();
byte[] raw_name = encoding.GetBytes (name);
if (raw_name.Length > arc_options.NameLength)
throw new InvalidFileName (entry.Name, arcStrings.MsgFileNameTooLong);
ArcDirectory dir;
if (!file_table.TryGetValue (ext, out dir))
{
byte[] raw_ext = encoding.GetBytes (ext);
if (raw_ext.Length > 3)
throw new InvalidFileName (entry.Name, arcStrings.MsgExtensionTooLong);
dir = new ArcDirectory { Extension = raw_ext, Files = new List<ArcEntry>() };
file_table[ext] = dir;
}
dir.Files.Add (new ArcEntry { Name = entry.Name, RawName = raw_name });
++file_count;
}
if (null != callback)
callback (file_count+1, null, null);
int callback_count = 0;
long dir_offset = 4 + file_table.Count * 12;
long data_offset = dir_offset + (arc_options.NameLength + 9) * file_count;
output.Position = data_offset;
foreach (var ext in file_table.Keys)
{
var dir = file_table[ext];
dir.DirOffset = (uint)dir_offset;
dir_offset += (arc_options.NameLength + 9) * dir.Files.Count;
foreach (var entry in dir.Files)
{
if (null != callback)
callback (callback_count++, entry, arcStrings.MsgAddingFile);
entry.Offset = data_offset;
using (var input = File.OpenRead (entry.Name))
{
var size = input.Length;
if (size > uint.MaxValue || data_offset + size > uint.MaxValue)
throw new FileSizeException();
data_offset += size;
entry.Size = (uint)size;
input.CopyTo (output);
}
}
}
if (null != callback)
callback (callback_count++, null, arcStrings.MsgWritingIndex);
output.Position = 0;
using (var header = new BinaryWriter (output, encoding, true))
{
byte[] buffer = new byte[arc_options.NameLength+1];
header.Write (file_table.Count);
foreach (var ext in file_table)
{
Array.Copy (ext.Value.Extension, buffer, ext.Value.Extension.Length);
for (int i = ext.Value.Extension.Length; i < 4; ++i)
buffer[i] = 0;
header.Write (buffer, 0, 4);
header.Write (ext.Value.Files.Count);
header.Write (ext.Value.DirOffset);
}
foreach (var ext in file_table)
{
foreach (var entry in ext.Value.Files)
{
Array.Copy (entry.RawName, buffer, entry.RawName.Length);
for (int i = entry.RawName.Length; i < buffer.Length; ++i)
buffer[i] = 0;
header.Write (buffer);
header.Write (entry.Size);
header.Write ((uint)entry.Offset);
}
}
}
}
}
}

View File

@@ -84,11 +84,14 @@ namespace GameRes.Formats.KiriKiri
public static readonly Dictionary<string, ICrypt> KnownSchemes = new Dictionary<string, ICrypt> {
{ arcStrings.ArcNoEncryption, NoCryptAlgorithm },
{ "Fate/Stay Night", new FateCrypt() },
{ "Swan Song", new SwanSongCrypt() },
{ "Cafe Sourire", new XorCrypt (0xcd) },
{ "Seirei Tenshou", new SeitenCrypt() },
{ "Coμ", new ComyuCrypt() },
{ "Fate/hollow ataraxia", new FateHACrypt() },
{ "Fate/stay night", new FateCrypt() },
{ "Imouto Style", new ImoutoStyleCrypt() },
{ "Okiba ga Nai!", new OkibaCrypt() },
{ "Seirei Tenshou", new SeitenCrypt() },
{ "Swan Song", new SwanSongCrypt() },
};
public override ArcFile TryOpen (ArcView file)
@@ -104,7 +107,7 @@ namespace GameRes.Formats.KiriKiri
return null;
dir_offset = file.View.ReadInt64 (0x20);
}
if (dir_offset >= file.MaxOffset)
if (dir_offset < 0x13 || dir_offset >= file.MaxOffset)
return null;
int header_type = file.View.ReadByte (dir_offset);
@@ -229,10 +232,6 @@ namespace GameRes.Formats.KiriKiri
if (!string.IsNullOrEmpty (entry.Name) && entry.Segments.Any())
{
dir.Add (entry);
// Trace.WriteLine (string.Format ("{0,-16} {3:X8} {1,11} {2,12}", entry.Name,
// entry.IsEncrypted ? "[encrypted]" : "",
// entry.Segments.First().IsCompressed ? "[compressed]" : "",
// entry.Hash));
}
NextEntry:
header.BaseStream.Position = dir_offset;
@@ -246,6 +245,10 @@ NextEntry:
var xp3_entry = entry as Xp3Entry;
if (null == xp3_entry)
return arc.File.CreateStream (entry.Offset, entry.Size);
// Trace.WriteLine (string.Format ("{0,-16} {3:X8} {1,11} {2,12}", xp3_entry.Name,
// xp3_entry.IsEncrypted ? "[encrypted]" : "",
// xp3_entry.Segments.First().IsCompressed ? "[compressed]" : "",
// xp3_entry.Hash));
if (1 == xp3_entry.Segments.Count && !xp3_entry.IsEncrypted)
{
var segment = xp3_entry.Segments.First();
@@ -287,11 +290,9 @@ NextEntry:
public static ICrypt GetScheme (string scheme)
{
ICrypt algorithm = NoCryptAlgorithm;
if (!string.IsNullOrEmpty (scheme))
{
KnownSchemes.TryGetValue (scheme, out algorithm);
}
ICrypt algorithm;
if (string.IsNullOrEmpty (scheme) || !KnownSchemes.TryGetValue (scheme, out algorithm))
algorithm = NoCryptAlgorithm;
return algorithm;
}
@@ -422,7 +423,7 @@ NextEntry:
}
header.BaseStream.Position = 0;
writer.Write ((byte)(compress_index ? 1 : 0));
writer.Write (compress_index);
long unpacked_dir_size = header.BaseStream.Length;
if (compress_index)
{
@@ -588,7 +589,7 @@ NextEntry:
long m_offset = 0;
bool m_eof = false;
public override bool CanRead { get { return true; } }
public override bool CanRead { get { return m_stream != null; } }
public override bool CanSeek { get { return false; } }
public override bool CanWrite { get { return false; } }
public override long Length { get { return m_entry.UnpackedSize; } }
@@ -616,11 +617,9 @@ NextEntry:
if (null != m_stream)
m_stream.Dispose();
var segment = m_segment.Current;
m_stream = m_file.CreateStream (segment.Offset, segment.Size);
if (segment.IsCompressed)
m_stream = new ZLibStream (m_file.CreateStream (segment.Offset, segment.PackedSize),
CompressionMode.Decompress);
else
m_stream = m_file.CreateStream (segment.Offset, segment.Size);
m_stream = new ZLibStream (m_stream, CompressionMode.Decompress);
}
public override int Read (byte[] buffer, int offset, int count)

View File

@@ -222,7 +222,7 @@ namespace GameRes.Formats.YuRis
writer.Write (name_len);
writer.Write (entry.IndexName);
writer.Write (entry.FileType);
writer.Write ((byte)(entry.IsPacked ? 1 : 0));
writer.Write (entry.IsPacked);
writer.Write (entry.UnpackedSize);
writer.Write (entry.Size);
writer.Write ((uint)entry.Offset);

View File

@@ -0,0 +1,16 @@
<Grid x:Class="GameRes.Formats.GUI.CreateWARCWidget"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:GameRes.Formats.Strings"
xmlns:p="clr-namespace:GameRes.Formats.Properties">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="{x:Static s:arcStrings.WARCLabelLength}" Target="{Binding ElementName=NameLength}" Grid.Column="0" Margin="0"/>
<ComboBox Name="NameLength" Width="40" SelectedValuePath="Content" Grid.Column="1" Margin="8"
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=WARCNameLength, Mode=TwoWay}">
<ComboBoxItem Content="8"/>
<ComboBoxItem Content="12"/>
</ComboBox>
</Grid>

View File

@@ -0,0 +1,15 @@
using System.Windows.Controls;
namespace GameRes.Formats.GUI
{
/// <summary>
/// Interaction logic for CreateWARCWidget.xaml
/// </summary>
public partial class CreateWARCWidget : Grid
{
public CreateWARCWidget ()
{
InitializeComponent ();
}
}
}

View File

@@ -95,12 +95,12 @@ namespace GameRes.Formats.DRS
int stride = (int)info.Width*((info.BPP+7)/8);
if (8 == info.BPP)
{
file.Position = 44;
format = PixelFormats.Indexed8;
var palette_data = new byte[0x400];
if (palette_data.Length != file.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
var palette = new Color[256];
file.Position = 44;
for (int i = 0; i < 256; ++i)
{
palette[i] = Color.FromRgb (palette_data[i*4+2], palette_data[i*4+1], palette_data[i*4]);

230
ArcFormats/ImageWIP.cs Normal file
View File

@@ -0,0 +1,230 @@
//! \file ImageWIP.cs
//! \date Fri Oct 31 14:52:49 2014
//! \brief Will image format implementation.
//
// Copyright (C) 2014 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
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.ComponentModel.Composition;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace GameRes.Formats.Will
{
internal class WipMetaData : ImageMetaData
{
public int FrameCount;
public uint FrameSize;
}
[Export(typeof(ImageFormat))]
public class WipFormat : ImageFormat
{
public override string Tag { get { return "WIP"; } }
public override string Description { get { return "Will Co. image format"; } }
public override uint Signature { get { return 0x46504957u; } } // 'WIPF'
public WipFormat ()
{
Extensions = new string[] { "wip", "msk" };
}
public override ImageMetaData ReadMetaData (Stream stream)
{
using (var file = new BinaryReader (stream, Encoding.ASCII, true))
{
if (Signature != file.ReadUInt32())
return null;
int frames = file.ReadUInt16();
int bpp = file.ReadUInt16();
uint width = file.ReadUInt32();
uint height = file.ReadUInt32();
int x = file.ReadInt32();
int y = file.ReadInt32();
file.ReadUInt32(); // 0
uint frame_size = file.ReadUInt32();
if (24 != bpp && 8 != bpp)
{
Trace.WriteLine ("unsupported bpp", "WipFormat");
return null;
}
if (frames > 1)
Trace.WriteLine ("Extra frames ignored", "WipFormat");
return new WipMetaData
{
Width = width,
Height = height,
OffsetX = x,
OffsetY = y,
BPP = bpp,
FrameCount = frames,
FrameSize = frame_size,
};
}
}
public override void Write (Stream file, ImageData image)
{
throw new NotImplementedException ("WipFormat.Write not implemented");
}
public override ImageData Read (Stream file, ImageMetaData info)
{
var meta = info as WipMetaData;
if (null == meta)
throw new ArgumentException ("WipFormat.Read should be supplied with WipMetaData", "info");
file.Position = 8 + 24 * meta.FrameCount;
Color[] palette = null;
if (8 == meta.BPP)
{
var palette_data = new byte[0x400];
if (palette_data.Length != file.Read (palette_data, 0, palette_data.Length))
throw new InvalidFormatException();
palette = new Color[0x100];
for (int i = 0; i < 0x100; ++i)
{
palette[i] = Color.FromRgb (palette_data[i*4], palette_data[i*4+1], palette_data[i*4+2]);
}
}
using (var reader = new Reader (file, meta))
{
reader.Unpack();
BitmapSource bitmap;
if (24 == meta.BPP)
{
byte[] raw = reader.Data;
int size = (int)meta.Width * (int)meta.Height;
byte[] pixels = new byte[size*3];
for (int i = 0; i < size; ++i)
{
pixels[i*3] = raw[i];
pixels[i*3+1] = raw[i+size];
pixels[i*3+2] = raw[i+size*2];
}
bitmap = BitmapSource.Create ((int)meta.Width, (int)meta.Height, 96, 96,
PixelFormats.Bgr24, null, pixels, (int)meta.Width*3);
}
else if (8 == meta.BPP)
{
byte[] pixels = reader.Data;
bitmap = BitmapSource.Create ((int)meta.Width, (int)meta.Height, 96, 96,
PixelFormats.Indexed8, new BitmapPalette (palette), pixels, (int)meta.Width);
}
else
throw new InvalidFormatException();
bitmap.Freeze();
return new ImageData (bitmap, meta);
}
}
internal class Reader : IDisposable
{
private BinaryReader m_input;
private uint m_length;
private byte[] m_data;
public byte[] Data { get { return m_data; } }
public Reader (Stream file, WipMetaData info)
{
m_length = info.FrameSize;
// int stride = (int)info.Width*((info.BPP+7)/8);
int stride = (int)info.Width*4;
m_data = new byte[stride * (int)info.Height];
m_input = new BinaryReader (file, Encoding.ASCII, true);
}
private byte[] m_window = new byte[0x1000];
public void Unpack ()
{
int current = 0;
int window_index = 1;
int control = 0;
byte input = 0;
for (uint length = m_length; length > 0; )
{
control >>= 1;
if (0 == (control & 0x100))
{
input = m_input.ReadByte();
--length;
control = input | 0xff00;
}
if (0 != (control & 1))
{
if (length < 1)
throw new InvalidFormatException();
input = m_input.ReadByte();
--length;
m_data[current++] = input;
m_window[window_index++] = input;
window_index &= 0xfff;
}
else
{
if (length < 2)
throw new InvalidFormatException();
int di = m_input.ReadByte();
input = m_input.ReadByte();
length -= 2;
int offset = ((di << 8) | input) >> 4;
int count = (input & 0xf) + 2;
for (int i = 0; i < count; ++i)
{
int src = (i + offset) & 0xfff;
input = m_window[src];
m_data[current++] = input;
m_window[window_index++] = input;
window_index &= 0xfff;
}
}
}
}
#region IDisposable Members
bool disposed = false;
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
if (!disposed)
{
if (disposing)
m_input.Dispose();
m_input = null;
m_data = null;
disposed = true;
}
}
#endregion
}
}
}

941
ArcFormats/KiriKiriCx.cs Normal file
View File

@@ -0,0 +1,941 @@
//! \file KiriKiriCx.cs
//! \date Sun Sep 07 06:50:11 2014
//! \brief KiriKiri Cx encryption scheme implementation.
//
// Copyright (C) 2014 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
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace GameRes.Formats.KiriKiri
{
public class CxProgramException : ApplicationException
{
public CxProgramException (string message) : base (message)
{
}
}
internal abstract class CxEncryption : ICrypt
{
private uint m_mask;
private uint m_offset;
protected byte[] PrologOrder { get; set; }
protected byte[] OddBranchOrder { get; set; }
protected byte[] EvenBranchOrder { get; set; }
protected abstract uint[] ControlBlock { get; }
public CxEncryption (uint mask, uint offset)
{
m_mask = mask;
m_offset = offset;
PrologOrder = new byte[] { 0, 1, 2 };
OddBranchOrder = new byte[] { 0, 1, 2, 3, 4, 5 };
EvenBranchOrder = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
}
uint GetBaseOffset (uint hash)
{
return (hash & m_mask) + m_offset;
}
public override byte Decrypt (Xp3Entry entry, long offset, byte value)
{
uint key = entry.Hash;
uint base_offset = GetBaseOffset (key);
if (offset >= base_offset)
{
key = (key >> 16) ^ key;
}
var buffer = new byte[1] { value };
Decode (key, offset, buffer, 0, 1);
return buffer[0];
}
public override void Decrypt (Xp3Entry entry, long offset, byte[] buffer, int pos, int count)
{
uint key = entry.Hash;
uint base_offset = GetBaseOffset (key);
if (offset < base_offset)
{
int base_length = Math.Min ((int)(base_offset - offset), count);
Decode (key, offset, buffer, pos, base_length);
offset += base_length;
pos += base_length;
count -= base_length;
}
if (count > 0)
{
key = (key >> 16) ^ key;
Decode (key, offset, buffer, pos, count);
}
}
void Decode (uint key, long offset, byte[] buffer, int pos, int count)
{
Tuple<uint, uint> ret = ExecuteXCode (key);
uint key1 = ret.Item2 >> 16;
uint key2 = ret.Item2 & 0xffff;
byte key3 = (byte)(ret.Item1);
if (key1 == key2)
key2 = (key2+1) & 0xffff;
if (0 == key3)
key3 = 1;
// Trace.WriteLine (string.Format ("[offset:{3:x4}] [key1:{0:x4}] [key2:{1:x4}] [key3:{2:x6}]", key1, key2, key3, offset));
if ((key2 >= offset) && (key2 < offset + count))
buffer[pos + key2 - offset] ^= (byte)(ret.Item1 >> 16);
if ((key1 >= offset) && (key1 < offset + count))
buffer[pos + key1 - offset] ^= (byte)(ret.Item1 >> 8);
for (int i = 0; i < count; ++i)
buffer[pos + i] ^= key3;
}
public override void Encrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count)
{
Decrypt (entry, offset, values, pos, count);
}
CxProgram[] m_program_list = new CxProgram[0x80];
Tuple<uint, uint> ExecuteXCode (uint hash)
{
uint seed = hash & 0x7f;
if (null == m_program_list[seed])
{
m_program_list[seed] = GenerateProgram (seed);
}
hash >>= 7;
uint ret1 = m_program_list[seed].Execute (hash);
uint ret2 = m_program_list[seed].Execute (~hash);
return new Tuple<uint, uint> (ret1, ret2);
}
CxProgram GenerateProgram (uint seed)
{
var program = new CxProgram (seed, ControlBlock);
for (int stage = 5; stage > 0; --stage)
{
if (EmitCode (program, stage))
return program;
// Trace.WriteLine (string.Format ("stage {0} failed for seed {1}", stage, seed), "GenerateProgram");
program.Clear();
}
throw new CxProgramException ("Overly large CxEncryption bytecode");
}
bool EmitCode (CxProgram program, int stage)
{
return program.EmitNop (5) // 0x57 0x56 0x53 0x51 0x52
&& program.Emit (CxByteCode.MOV_EDI_ARG, 4) // 0x8b 0x7c 0x24 0x18
&& EmitBody (program, stage)
&& program.EmitNop (5) // 0x5a 0x59 0x5b 0x5e 0x5f
&& program.Emit (CxByteCode.RETN); // 0xc3
}
bool EmitBody (CxProgram program, int stage)
{
if (1 == stage)
return EmitProlog (program);
if (!program.Emit (CxByteCode.PUSH_EBX)) // 0x53
return false;
if (0 != (program.GetRandom() & 1))
{
if (!EmitBody (program, stage - 1))
return false;
}
else if (!EmitBody2 (program, stage - 1))
return false;
if (!program.Emit (CxByteCode.MOV_EBX_EAX, 2)) // 0x89 0xc3
return false;
if (0 != (program.GetRandom() & 1))
{
if (!EmitBody (program, stage - 1))
return false;
}
else if (!EmitBody2 (program, stage - 1))
return false;
return EmitOddBranch (program) && program.Emit (CxByteCode.POP_EBX); // 0x5b
}
bool EmitBody2 (CxProgram program, int stage)
{
if (1 == stage)
return EmitProlog (program);
bool rc = true;
if (0 != (program.GetRandom() & 1))
rc = EmitBody (program, stage - 1);
else
rc = EmitBody2 (program, stage - 1);
return rc && EmitEvenBranch (program);
}
bool EmitProlog (CxProgram program)
{
bool rc = true;
switch (PrologOrder[program.GetRandom() % 3])
{
case 2:
// MOV EAX, (Random() & 0x3ff)
// MOV EAX, EncryptionControlBlock[EAX]
rc = program.EmitNop (5) // 0xbe
&& program.Emit (CxByteCode.MOV_EAX_IMMED, 2) // 0x8b 0x86
&& program.EmitUInt32 (program.GetRandom() & 0x3ff)
&& program.Emit (CxByteCode.MOV_EAX_INDIRECT, 0);
break;
case 1:
rc = program.Emit (CxByteCode.MOV_EAX_EDI, 2); // 0x8b 0xc7
break;
case 0:
// MOV EAX, Random()
rc = program.Emit (CxByteCode.MOV_EAX_IMMED) // 0xb8
&& program.EmitRandom();
break;
}
return rc;
}
bool EmitEvenBranch (CxProgram program)
{
bool rc = true;
switch (EvenBranchOrder[program.GetRandom() & 7])
{
case 0:
rc = program.Emit (CxByteCode.NOT_EAX, 2); // 0xf7 0xd0
break;
case 1:
rc = program.Emit (CxByteCode.DEC_EAX); // 0x48
break;
case 2:
rc = program.Emit (CxByteCode.NEG_EAX, 2); // 0xf7 0xd8
break;
case 3:
rc = program.Emit (CxByteCode.INC_EAX); // 0x40
break;
case 4:
rc = program.EmitNop (5) // 0xbe
&& program.Emit (CxByteCode.AND_EAX_IMMED) // 0x25
&& program.EmitUInt32 (0x3ff)
&& program.Emit (CxByteCode.MOV_EAX_INDIRECT, 3); // 0x8b 0x04 0x86
break;
case 5:
rc = program.Emit (CxByteCode.PUSH_EBX) // 0x53
&& program.Emit (CxByteCode.MOV_EBX_EAX, 2) // 0x89 0xc3
&& program.Emit (CxByteCode.AND_EBX_IMMED, 2) // 0x81 0xe3
&& program.EmitUInt32 (0xaaaaaaaa)
&& program.Emit (CxByteCode.AND_EAX_IMMED) // 0x25
&& program.EmitUInt32 (0x55555555)
&& program.Emit (CxByteCode.SHR_EBX_1, 2) // 0xd1 0xeb
&& program.Emit (CxByteCode.SHL_EAX_1, 2) // 0xd1 0xe0
&& program.Emit (CxByteCode.OR_EAX_EBX, 2) // 0x09 0xd8
&& program.Emit (CxByteCode.POP_EBX); // 0x5b
break;
case 6:
rc = program.Emit (CxByteCode.XOR_EAX_IMMED) // 0x35
&& program.EmitRandom();
break;
case 7:
if (0 != (program.GetRandom() & 1))
rc = program.Emit (CxByteCode.ADD_EAX_IMMED); // 0x05
else
rc = program.Emit (CxByteCode.SUB_EAX_IMMED); // 0x2d
rc = rc && program.EmitRandom();
break;
}
return rc;
}
bool EmitOddBranch (CxProgram program)
{
bool rc = true;
switch (OddBranchOrder[program.GetRandom() % 6])
{
case 0:
rc = program.Emit (CxByteCode.PUSH_ECX) // 0x51
&& program.Emit (CxByteCode.MOV_ECX_EBX, 2) // 0x89 0xd9
&& program.Emit (CxByteCode.AND_ECX_0F, 3) // 0x83 0xe1 0x0f
&& program.Emit (CxByteCode.SHR_EAX_CL, 2) // 0xd3 0xe8
&& program.Emit (CxByteCode.POP_ECX); // 0x59
break;
case 1:
rc = program.Emit (CxByteCode.PUSH_ECX) // 0x51
&& program.Emit (CxByteCode.MOV_ECX_EBX, 2) // 0x89 0xd9
&& program.Emit (CxByteCode.AND_ECX_0F, 3) // 0x83 0xe1 0x0f
&& program.Emit (CxByteCode.SHL_EAX_CL, 2) // 0xd3 0xe0
&& program.Emit (CxByteCode.POP_ECX); // 0x59
break;
case 2:
rc = program.Emit (CxByteCode.ADD_EAX_EBX, 2); // 0x01 0xd8
break;
case 3:
rc = program.Emit (CxByteCode.NEG_EAX, 2) // 0xf7 0xd8
&& program.Emit (CxByteCode.ADD_EAX_EBX, 2); // 0x01 0xd8
break;
case 4:
rc = program.Emit (CxByteCode.IMUL_EAX_EBX, 3); // 0x0f 0xaf 0xc3
break;
case 5:
rc = program.Emit (CxByteCode.SUB_EAX_EBX, 2); // 0x29 0xd8
break;
}
return rc;
}
}
enum CxByteCode
{
NOP,
RETN,
MOV_EDI_ARG,
PUSH_EBX,
POP_EBX,
PUSH_ECX,
POP_ECX,
MOV_EAX_EBX,
MOV_EBX_EAX,
MOV_ECX_EBX,
MOV_EAX_CONTROL_BLOCK,
MOV_EAX_EDI,
MOV_EAX_INDIRECT,
ADD_EAX_EBX,
SUB_EAX_EBX,
IMUL_EAX_EBX,
AND_ECX_0F,
SHR_EBX_1,
SHL_EAX_1,
SHR_EAX_CL,
SHL_EAX_CL,
OR_EAX_EBX,
NOT_EAX,
NEG_EAX,
DEC_EAX,
INC_EAX,
IMMED = 0x100,
MOV_EAX_IMMED,
AND_EBX_IMMED,
AND_EAX_IMMED,
XOR_EAX_IMMED,
ADD_EAX_IMMED,
SUB_EAX_IMMED,
}
internal class CxProgram
{
public const int LengthLimit = 0x80;
private List<uint> m_code = new List<uint> (LengthLimit);
private uint[] m_ControlBlock;
private int m_length;
private uint m_seed;
class Context
{
public uint eax;
public uint ebx;
public uint ecx;
public uint edi;
public Stack<uint> stack = new Stack<uint>();
}
public CxProgram (uint seed, uint[] control_block)
{
m_seed = seed;
m_length = 0;
m_ControlBlock = control_block;
}
public uint Execute (uint hash)
{
var context = new Context();
var iterator = m_code.GetEnumerator();
uint immed = 0;
while (iterator.MoveNext())
{
var bytecode = (CxByteCode)iterator.Current;
if (CxByteCode.IMMED == (bytecode & CxByteCode.IMMED))
{
if (!iterator.MoveNext())
throw new CxProgramException ("Incomplete IMMED bytecode in CxEncryption program");
immed = iterator.Current;
}
switch (bytecode)
{
case CxByteCode.NOP: break;
case CxByteCode.IMMED: break;
case CxByteCode.MOV_EDI_ARG: context.edi = hash; break;
case CxByteCode.PUSH_EBX: context.stack.Push (context.ebx); break;
case CxByteCode.POP_EBX: context.ebx = context.stack.Pop(); break;
case CxByteCode.PUSH_ECX: context.stack.Push (context.ecx); break;
case CxByteCode.POP_ECX: context.ecx = context.stack.Pop(); break;
case CxByteCode.MOV_EBX_EAX: context.ebx = context.eax; break;
case CxByteCode.MOV_EAX_EDI: context.eax = context.edi; break;
case CxByteCode.MOV_ECX_EBX: context.ecx = context.ebx; break;
case CxByteCode.MOV_EAX_EBX: context.eax = context.ebx; break;
case CxByteCode.AND_ECX_0F: context.ecx &= 0x0f; break;
case CxByteCode.SHR_EBX_1: context.ebx >>= 1; break;
case CxByteCode.SHL_EAX_1: context.eax <<= 1; break;
case CxByteCode.SHR_EAX_CL: context.eax >>= (int)context.ecx; break;
case CxByteCode.SHL_EAX_CL: context.eax <<= (int)context.ecx; break;
case CxByteCode.OR_EAX_EBX: context.eax |= context.ebx; break;
case CxByteCode.NOT_EAX: context.eax = ~context.eax; break;
case CxByteCode.NEG_EAX: context.eax = (uint)-context.eax; break;
case CxByteCode.DEC_EAX: context.eax--; break;
case CxByteCode.INC_EAX: context.eax++; break;
case CxByteCode.ADD_EAX_EBX: context.eax += context.ebx; break;
case CxByteCode.SUB_EAX_EBX: context.eax -= context.ebx; break;
case CxByteCode.IMUL_EAX_EBX: context.eax *= context.ebx; break;
case CxByteCode.ADD_EAX_IMMED: context.eax += immed; break;
case CxByteCode.SUB_EAX_IMMED: context.eax -= immed; break;
case CxByteCode.AND_EBX_IMMED: context.ebx &= immed; break;
case CxByteCode.AND_EAX_IMMED: context.eax &= immed; break;
case CxByteCode.XOR_EAX_IMMED: context.eax ^= immed; break;
case CxByteCode.MOV_EAX_IMMED: context.eax = immed; break;
case CxByteCode.MOV_EAX_INDIRECT:
if (context.eax >= m_ControlBlock.Length)
throw new CxProgramException ("Index out of bounds in CxEncryption program");
context.eax = ~m_ControlBlock[context.eax];
break;
case CxByteCode.RETN:
if (context.stack.Count > 0)
throw new CxProgramException ("Imbalanced stack in CxEncryption program");
return context.eax;
default:
throw new CxProgramException ("Invalid bytecode in CxEncryption program");
}
}
throw new CxProgramException ("CxEncryption program without RETN bytecode");
}
public void Clear ()
{
m_length = 0;
m_code.Clear();
}
public bool EmitNop (int count)
{
if (m_length + count > LengthLimit)
return false;
m_length += count;
return true;
}
public bool Emit (CxByteCode code, int length = 1)
{
if (m_length + length > LengthLimit)
return false;
m_length += length;
m_code.Add ((uint)code);
return true;
}
public bool EmitUInt32 (uint x)
{
if (m_length + 4 > LengthLimit)
return false;
m_length += 4;
m_code.Add (x);
return true;
}
public bool EmitRandom ()
{
return EmitUInt32 (GetRandom());
}
public uint GetRandom ()
{
uint seed = m_seed;
m_seed = 1103515245 * seed + 12345;
return m_seed ^ (seed << 16) ^ (seed >> 16);
}
}
internal class FateHACrypt : CxEncryption
{
public FateHACrypt () : base (0x143, 0x787)
{
}
protected override uint[] ControlBlock { get { return FateControlBlock; } }
static readonly uint[] FateControlBlock = new uint[] {
0x9c91badf, 0x8b8f868d, 0xdf919096, 0x8b91909c, 0xdf93908d, 0x9c90939d, 0xd2d2df94, 0x9e8bacdf,
0x9e9c968b, 0xdf869393, 0x9bdf8d90, 0x929e9186, 0x939e9c96, 0xdfd38693, 0x9a8d969b, 0x86938b9c,
0xdf8d90df, 0x969b9196, 0x8b9c9a8d, 0xdfd38693, 0x91968c8a, 0x978bdf98, 0x8fdf8c96, 0x8d98908d,
0x9edf929e, 0x90d09b91, 0x939ddf8d, 0xdf949c90, 0x92908d99, 0x978b90df, 0x8fdf8d9a, 0x8d98908d,
0xdf8c929e, 0x93939688, 0xdf9a9ddf, 0x9a939396, 0xdf939e98, 0x8bdf869d, 0x93df9a97, 0x919a9c96,
0x9edf9a8c, 0x9a9a8d98, 0x8b919a92, 0x4e7ddfd1, 0x897c337d, 0xb07c727c, 0x7f7c767c, 0x8a7c1d7d,
0x9d7c727c, 0x0f7db17c, 0x3c6fbe7e, 0x3a7db66c, 0x157d5f7d, 0xb66c516c, 0x5f7d3a7d, 0xbe7e157d,
0x256f436d, 0x3a7db66c, 0x157d5f7d, 0x256f2b75, 0x3a7db66c, 0x157d5f7d, 0x436ebe7e, 0x897c337d,
0xb07c727c, 0x7f7c767c, 0x187d567d, 0x5d7d8f68, 0x4e7d167d, 0x327d397d, 0xbc7c767c, 0x6c7ca57c,
0x367da77c, 0x177d197d, 0x497d2974, 0x157d187d, 0x5d7d3b7d, 0x487d237d, 0x71f5bd7e, 0x7d116e56,
0x7dbe7436, 0x69397d16, 0x7d557d7a, 0x7d4e7d36, 0x7d4e7d36, 0x703b7d4a, 0x7d827390, 0x7d3b7d59,
0x7d157d52, 0xf5bd7e16, 0x53708a7e, 0x337d4f6d, 0x2e6b8a1f, 0x207d9374, 0xa37c0f7d, 0xa57ca47e,
0xa87ca47e, 0x8968337d, 0x3a7d3368, 0x157d1d7d, 0x92df317d, 0x869e938f, 0x557d8d9a, 0x496f3b72,
0x157d4c7d, 0x1a6ebe7e, 0x6571337d, 0x377d367d, 0x427d3e7d, 0x2b6e0c70, 0x337d3a7d, 0xa870be7e,
0x377d9c6d, 0x567d0e7d, 0x377d306a, 0x497d4b75, 0x2074367d, 0x0c705d7d, 0x3a7d2b6e, 0xa47e327d,
0x6ef5897e, 0x7d306a75, 0x7d187d12, 0x7d427647, 0x7d41730f, 0x7d3b7d3e, 0x7d337d16, 0x7d127d56,
0x7d187d56, 0x7d5d7d37, 0x7dbe7e55, 0x7d2b7d42, 0x7d93690e, 0x7342750f, 0x7d4a7d82, 0x7d527d3b,
0x7d3b7d15, 0x7d167d5d, 0x7d417d33, 0x7e5b7d14, 0x70216bbd, 0x7d327d68, 0x7d367d37, 0x7d1d7d18,
0x7d157d5b, 0x7d4f7d4a, 0x7d8a7e36, 0x7d167d20, 0x7d327d32, 0x7d327d20, 0x7e507d15, 0x7d157db4,
0x7d157d50, 0x7d157d50, 0x7d327d15, 0x7d327d15, 0x7d157d32, 0x7d147d20, 0x7e147d20, 0x73397d89,
0x7d5d7d41, 0x7d557d37, 0x69be7e18, 0x75337d93, 0x70397d6c, 0x7d7a6d1c, 0x7d0c710f, 0x7d197150,
0x7e427d3e, 0x6bf5f5bd, 0x7d687021, 0x7d4e7d55, 0x7d377d5b, 0x7d3b7d3e, 0x7d237d4a, 0x7d427d3e,
0x7d327d33, 0x7d4a7d42, 0x7c157756, 0x6e717369, 0x7d417db0, 0x7d427d3e, 0x7d147d41, 0x7e567d5b,
0x7d7a69bd, 0x68406832, 0x7d796d62, 0x7d4e7d36, 0x7d377d0e, 0x7d397d4e, 0x6e04730f, 0x7d3e7d69,
0xf5bd7e42, 0x51758a7e, 0x367dac6e, 0x207d1d68, 0x187d427d, 0x4472be7e, 0x0f7d636c, 0x98cacedf,
0x597d3e76, 0xbe7e3b7d, 0x556a436b, 0x187d527d, 0x53725d7d, 0x3e7d4b7d, 0x397d427d, 0x147d4e7d,
0xbe7e3a7d, 0x2e6b8a1f, 0x6c7cab7c, 0xbe7e327d, 0x5b7d1f7d, 0xb0710e6c, 0x3a7d936f, 0x897e487d,
0x7d9369f5, 0x7d5f7d32, 0x7d3b7d12, 0x6840683b, 0x7d0f7d62, 0x7d207d1d, 0x7e467d4c, 0x70216bbe,
0x740f7d68, 0x7d237d87, 0x7e427d46, 0x7d7a69bd, 0x73427632, 0x6a567133, 0x68557d55, 0x7d626840,
0x7d1d7d0f, 0x7d4c7d20, 0x7d187d46, 0x7d427d15, 0x68567d33, 0x7d0f7662, 0x7d547d3a, 0x7d5d7d37,
0x7d5b7d19, 0x70a36a37, 0x7d417d11, 0x7d427d3e, 0x7dbe7e55, 0x77157d44, 0x7e776837, 0x70216bbe,
0x73337d68, 0x7d8b6841, 0x76626832, 0x6b8c6a0f, 0x7d367da3, 0x7d3e7d37, 0xf5bd7e42, 0x70216bf5,
0x73327d68, 0x7d3e7d41, 0x7d5d7d3b, 0x7d4e7d16, 0x77557d39, 0x6a5e692c, 0x7d41698c, 0x7d417d37,
0x7e3a7d50, 0x728971be, 0x6e567193, 0x7d327d33, 0x7d397d23, 0x7d377d1f, 0x7d5b7d19, 0x7d337d37,
0x72be7e3a, 0x7d20743a, 0x7d5f7d32, 0x69177d23, 0x741f7d93, 0x7d367dbc, 0x7d3b7d4a, 0x7d377d5d,
0x7dbd7e5d, 0x7d397d1f, 0x77397d1f, 0x7d576a3f, 0x7d567d41, 0x7dbe7e18, 0x7d5d7d39, 0x7d337d5b,
0x7d5f7d1f, 0x7dbd7e16, 0x7d3e7d39, 0x71367d52, 0x7d42690a, 0x7d207632, 0x7d3b7d53, 0x7d167d5d,
0x7d507d12, 0x7e4a7d41, 0x684068be, 0x69156f62, 0x7c337d1a, 0x7c6c7cbe, 0x7c727c97, 0x7d977cbc,
0x71397636, 0x6bac6e69, 0x7d0f7d35, 0x7d187d1d, 0x7d3b7d46, 0x7d167d5d, 0x7d417d0e, 0x76187d56,
0x76766a20, 0x7d557d28, 0x7d567d56, 0x7d3b7d3e, 0x7d337d16, 0x7d556a32, 0x7d3e7d56, 0x7d5d7d3b,
0xf5bd7e16, 0x7d397df5, 0x7d417332, 0x7d3b7d3e, 0x7e9c7e1f, 0x7e9c7e9c, 0x684068bd, 0x7d796d62,
0x7d8a7e36, 0x711f7d3a, 0x7c1f7d17, 0x7c907c93, 0x7e907c93, 0x7d3d7d9f, 0x7d3a7d5d, 0x7dbc7136,
0x7c427d3e, 0x7caa7cb2, 0x7caa7cb2, 0x7c767c8b, 0x7c8f7cbc, 0x7c1f7d6c, 0x7c907c93, 0x7e907c93,
0x7d3d7d9f, 0x7d3a7d5d, 0x7dbc7136, 0x7c427d3e, 0x7caa7cb2, 0x7caa7cb2, 0x7c767c8b, 0x7c8f7cbc,
0x7c1f7d6c, 0x7c907c93, 0x7e907c93, 0x7d3d7d9f, 0x7d3a7d5d, 0x7dbc7136, 0x7c427d3e, 0x7caa7cb2,
0x7caa7cb2, 0x7c767c8b, 0x7c8f7cbc, 0x7c1f7d6c, 0x7c907c93, 0x7e907c93, 0x7d3d7d9f, 0x7d3a7d5d,
0x7dbc7136, 0x7c427d3e, 0x7caa7cb2, 0x7caa7cb2, 0x7c767c8b, 0x7c8f7cbc, 0x7c1f7d6c, 0x7c907c93,
0x7e907c93, 0x7d3d7d9f, 0x7d3a7d5d, 0x7dbc7136, 0x7c427d3e, 0x7caa7cb2, 0x7caa7cb2, 0x7c767c8b,
0x7c8f7cbc, 0x7c1f7d6c, 0x7c907c93, 0x7e907c93, 0x7d3d7d9f, 0x7d3a7d5d, 0x7dbc7136, 0x7c427d3e,
0x7caa7cb2, 0x7caa7cb2, 0x7c767c8b, 0x7c8f7cbc, 0x7c1f7d6c, 0x7c907c93, 0x7e907c93, 0x7d3d7d9f,
0x7d3a7d5d, 0x7dbc7136, 0x7c427d3e, 0x7caa7cb2, 0x7caa7cb2, 0x7c767c8b, 0x7c8f7cbc, 0x7c1f7d6c,
0x7c907c93, 0x7e907c93, 0x7d3d7d9f, 0x7d3a7d5d, 0x7dbc7136, 0x7c427d3e, 0x7caa7cb2, 0x7caa7cb2,
0x7c767c8b, 0x7c8f7cbc, 0x7c1f7d6c, 0x7c907c93, 0x7e907c93, 0x7d897e9f, 0x6a567d39, 0x723376bf,
0x7d497d53, 0x763a7d17, 0x7d127d33, 0x7d167d15, 0x7dbe7e39, 0x7d3e7d5d, 0x765d7d42, 0x6f0f7d42,
0x7d127db7, 0x7d157d4c, 0x7d337d16, 0x700e6b56, 0x6a367d12, 0x7d3f778c, 0x7d377d36, 0xf5bd7e16,
0xccad251c, 0x01804437, 0xacf8d91d, 0xf4f495a3, 0xc07183e4, 0x617c1459, 0x279d2e94, 0x697cc3b8,
0x6f05547d, 0x97227782, 0xe5248bd1, 0xb5ebbdcc, 0x82a1cb76, 0x64687a74, 0xce35c18b, 0xe8905e50,
0xafffd2ce, 0x3612af4c, 0xf4bc0fcd, 0x64856fff, 0xead50cc7, 0x5066ed91, 0x7b0f0acf, 0x10cbc0d4,
0xa958c6fc, 0xe4707008, 0xd312636a, 0xd40c3361, 0xaf06d42d, 0x3f6808d2, 0xce796be4, 0x8b709456,
0xfae59248, 0xb6dddb98, 0xb7f56869, 0x14b68dbd, 0x5e5bd9ac, 0xdc8cd143, 0x41846e8e, 0xbf86a321,
0x18b857b3, 0x4db38b85, 0x53a083cc, 0x51336b61, 0x862243e1, 0xe047fbe1, 0xcdd48d79, 0xae3ab3be,
0x6524ddbb, 0xe64899da, 0x0367c27d, 0xdfa3b943, 0xf09ce1e4, 0x1b0f23cd, 0x25ff6afe, 0x82ea0625,
0xc011def6, 0x17600b48, 0xd3dd0e93, 0x548ddf45, 0x4fee40df, 0x3c26652e, 0xe99396f2, 0xa7dd4872,
0xb4a6ecaa, 0xa6da9022, 0xf6d10dd3, 0x2ef86186, 0x46c02be3, 0x9db7d8cf, 0xf410cc59, 0xf1c55546,
0xc7c9c416, 0x527dc4e1, 0x202ba1ea, 0x59d6de93, 0x2ea2c560, 0x138c7c6a, 0x1f8b369c, 0xf1d3f1e8,
0xee767328, 0x989440fe, 0x6ec3d8c5, 0xab83f151, 0xe41110ad, 0x33d88275, 0x9ed82668, 0xe6238d3e,
0xf4e9b036, 0xdfcf1a1c, 0x596aadbb, 0xb75bb192, 0x9b37c762, 0x78cd0322, 0xc0d8acd1, 0xa76d8757,
0xa71a0d57, 0xfe4c50cc, 0xd82f44cf, 0x8ea223e6, 0x73e8e602, 0x4f074710, 0x0f9715c9, 0x4b513841,
0x8c9b590a, 0xb22811da, 0x1bcb3180, 0xebbaf518, 0x8ab58fbb, 0x0c8effb7, 0x16fed8ab, 0x62f3f635,
0x966c212c, 0x2ae9a4cc, 0x42a4b17b, 0xe56fc4ad, 0xa7dca536, 0xc2e8597e, 0x07a05b93, 0x29ab3356,
0x24864a83, 0x7bffbc18, 0xd58fbd55, 0x2e8dd69c, 0xc145444c, 0x31840086, 0xc2cd2b55, 0x0bd3cb87,
0x01d4e666, 0xfc0d9c8c, 0x4af78c64, 0x0498df30, 0xf696e76e, 0xb1f13dad, 0x51824703, 0x9caeda64,
0xe3258725, 0xfc59f066, 0x838680e5, 0x36928f25, 0x16a1e088, 0x58a4be3f, 0x3e16541a, 0x9d9ca177,
0x6dcb242b, 0x786d809b, 0xcd736875, 0xaaea1072, 0x97604118, 0x3a14f5df, 0xfd0eb775, 0xfc68a624,
0xfe80b891, 0x177a10e1, 0xb221bc1a, 0x22a87b49, 0x6e0fd8b3, 0x9471faa0, 0xdc781156, 0xd1d955bb,
0xf06be41d, 0xae5f61d8, 0x3a4de399, 0x8ec113cb, 0xcd131c8a, 0x516825cf, 0xa7242dc1, 0xb27336c9,
0x7bdf287d, 0x3eb6d0ca, 0x1361ef6e, 0xd9298871, 0xd02c758e, 0x06123a76, 0xe6f7c422, 0x71e7d097,
0xc05bbc9e, 0xf2472301, 0x1d84add8, 0x2abbb422, 0x00c6f197, 0xc6a2948d, 0x0ec6b993, 0x49bfa4dc,
0x601a1b59, 0xa302e36f, 0xe107a92f, 0x9442e001, 0x518d0fad, 0x60ba8fb3, 0x7de05d29, 0x660220a6,
0x2305e532, 0xd4193ca6, 0x9669c8e2, 0x99844e6d, 0xa523f6d0, 0x3d768288, 0xff84aaa6, 0xdbb65d74,
0xd22caba8, 0x86e51c5f, 0x9ce3cba3, 0xa031be31, 0xc7eb8c81, 0x732e2e54, 0x1bd70a36, 0xabb9e07c,
0x1f6026ea, 0xf56c5ed4, 0x515d305d, 0xd2688e75, 0xf272f3e9, 0x5669847f, 0xd77f90c4, 0xc1655cb5,
0x981cff0e, 0xca2172e9, 0x80e68137, 0x04c28018, 0x17a1f61e, 0x5305dc98, 0x120b8ca4, 0xc8966d81,
0x48b88869, 0x99e34b6c, 0xcd813746, 0xa2c59dfd, 0xac8dcf74, 0x03debe30, 0x95788a09, 0xe5fc2c69,
0x76b5cf3d, 0x618c56e9, 0xda92dff8, 0xd961919d, 0x4806e3a8, 0x0ed09bff, 0xaced410e, 0x6878b0f9,
0x55d2a073, 0x5fe3eaa9, 0x86840ba7, 0x5106fa6e, 0xb90b8455, 0x470d632b, 0xc83fd88f, 0xd0a4fa65,
0x834c7227, 0x7d1a0d61, 0x9aa6746d, 0xdb0d9da5, 0x70c42d80, 0x99778095, 0x0a7e9b9e, 0x4619b7ce,
0x0b99295b, 0xbc912d1f, 0x4c397dcc, 0xf96b7ed0, 0x1096976d, 0xb1a978dc, 0x3b664a8f, 0x1edb01c1,
0x655cd150, 0xde516adf, 0x3da50d73, 0xd4018fe9, 0xe393b949, 0xb5bc6e0b, 0x575eca9e, 0x598a1ef6,
0xf2166833, 0x20224959, 0x4aff9f0d, 0x44ae2727, 0x34f63270, 0xf6b600d5, 0xfebdbf67, 0xa62f3e23,
0xd0ef945a, 0x6875d000, 0x4f1c9d74, 0x4c3b62fd, 0x076c9136, 0x73b7186e, 0x52bf8a6b, 0xded440a7,
0x9dd0e71c, 0x4c6a8036, 0x01c87ce8, 0x6a5c80cc, 0xff858cef, 0xd64bcfe4, 0x2d24b76f, 0xd36c6bd1,
0x9c4ca179, 0x8cdac4b6, 0x003ff1ea, 0xddc5b34c, 0x15d64b1a, 0xf5fa141f, 0x5812bf1f, 0x9bd50759,
0xc220bc8c, 0x934eb6f5, 0x6cd508e6, 0xc862d424, 0xc35b9d50, 0x538a1855, 0x871d4354, 0x2f6d55a3,
0xadcbf11f, 0xfba75a6c, 0x0d9d2bf1, 0x414f7db8, 0x3e7cc157, 0x9dba44fa, 0xd9d556e4, 0x7c7b0191,
0xa9f120f4, 0x56c2e1a7, 0xda660052, 0xc57e3127, 0x761f1df3, 0xfeb92f5b, 0x59b933d0, 0x5431e7af,
0x2a661b4d, 0x774d66b3, 0x74186a34, 0xc2e28dfb, 0xd99758e0, 0x5d4e8d31, 0x00ac0104, 0x7b404a77,
0xa5b9dbe6, 0x485d01d8, 0x78daf586, 0x8debafeb, 0x30ced20c, 0x0a2d79f2, 0x809695ac, 0x1cc31d1c,
0x79a647a8, 0x61a4c9ba, 0x41101d1d, 0xbae0aeaa, 0x5fed997a, 0x4688d100, 0x8cc6fe5c, 0xa0c23dc1,
0xdf13f396, 0x1942ee68, 0x953587fe, 0x89370d97, 0x85aba55d, 0xb87b9869, 0x2df88986, 0x6ec182e2,
0x0e232d62, 0xad503b2e, 0x5636c5a7, 0xd3a17cae, 0x426a9c64, 0x7a8e14b7, 0x5a14ad86, 0x96afc436,
0xfaa68137, 0x1b56f995, 0x3f7695c4, 0xb14d9592, 0xdc648fb9, 0x0bc7f21f, 0x8a2e4f76, 0x5619c3f5,
0x8047a43d, 0x0c76ed90, 0x0c4bf0ec, 0xb5d5f16a, 0xca043902, 0x2b16fc44, 0xda97feab, 0x97f3ed6d,
0x6cdcbcca, 0x423fc66f, 0x016e0ef3, 0xa0ed2304, 0xaaef9592, 0x9307f834, 0xe6cab837, 0xefb51bed,
0x7579964e, 0x3e09b1ed, 0x629ed018, 0xdc375c19, 0x1a765758, 0xaa132aa7, 0x37efa297, 0x9d8a54fd,
0x8b2d6de4, 0xfdaf5803, 0x4c7f84f7, 0x4f51e520, 0x25c791ed, 0xb4ae3f55, 0x30eb21a6, 0x10218782,
0xa1f328a6, 0x26600064, 0xf8222315, 0xa09386cd, 0x2c39af68, 0x8b09139e, 0x30ce56a6, 0x6112544c,
0xff62eaa6, 0x8f7d06b2, 0xdb4815b8, 0x0b868340, 0x1231da0b, 0x9bd1ebd1, 0x54840c1b, 0x248e42e9,
0xdbcd1327, 0x379e4966, 0xe9586a5d, 0xfb090b72, 0xf252c604, 0xdd9f0af7, 0x22a5fc71, 0x2db6d821,
0xebc4ddd4, 0x4a8d21e9, 0xbef971c2, 0x99797b4a, 0xd7d918bf, 0xe0272f88, 0x908488c2, 0xe6a697aa,
0x09f15f95, 0x21ead25e, 0x257f333e, 0x773219eb, 0xb4ee8710, 0x1388b5d4, 0x7df20323, 0x6ae56ce3,
0xc5ba6c40, 0x8e544d26, 0x926598c1, 0x1668a8b4, 0x6b67d1fc, 0x11e2e018, 0xb3fce656, 0xdde6f22a,
0x52469404, 0x2536ee5c, 0x2868e1ff, 0x5f4ce971, 0x47c4a8af, 0xefbbb6cf, 0xecd91b07, 0x929aad88,
0xe35010fd, 0xdf660e0a, 0x346c0adf, 0x2c0e0695, 0xd142aec4, 0x0007122f, 0xcb1db521, 0xf5dbcfa3,
0x1986d784, 0xa6590191, 0x8004d00b, 0x3cb5d898, 0x109b6212, 0x82b90029, 0xae090378, 0x2fa37649,
0xec0c9ede, 0x4eea87c2, 0x127e1796, 0x11c75395, 0x63f6685b, 0xa0add61c, 0xf3189340, 0x66533a49,
0xd548747a, 0x97f58fa9, 0xdc5581ef, 0xa7c8d34a, 0x9590eb0d, 0xee2a68c1, 0x21f39b12, 0x1d9ab21a,
0x0549c2c4, 0xac426ebf, 0x3b5eedf1, 0xa313c69a, 0x72e8f693, 0x4177233f, 0x6c6d41ca, 0xeda75e23,
0x9cc72f26, 0xf7b32b24, 0x791a1535, 0xd9b3046b, 0xed381a83, 0x96c212f6, 0x3298d4fc, 0xb2006d03,
0x236da0b4, 0x0d15b5fc, 0xcbc90ebc, 0xca6dff19, 0x28d410de, 0x0729bb85, 0x81ae90fb, 0x8f58f849,
0x93fca36d, 0x1b03aa91, 0x5524aab6, 0x1fb32602, 0xedcc6b65, 0xea4521f6, 0x8f98dd84, 0xe84fc42b,
0x1cf33210, 0x8f15111b, 0xa2537850, 0xaf5267dd, 0x87717c41, 0x111ab1af, 0x11fa5e31, 0x39f083e0,
0xf0ddf573, 0x523d6e0e, 0xfc16b1e0, 0x80139739, 0x7a285147, 0xfcc98900, 0xf6a57404, 0x5cc492c8,
0x18724e8b, 0xf799c3ca, 0xabebcb28, 0x8d8dbba8, 0x37c8a37d, 0x54de2b79, 0x9ac4abc2, 0xa40c3bb0,
0x09c5de57, 0xbf842d0b, 0xcfdc79aa, 0x9542c1b3, 0x4ca1174d, 0x6f611ce3, 0x76b07b17, 0x25bc42d2,
0xb9149fd7, 0x9506b278, 0xf5a249d0, 0x6e4ec763, 0x9f41fd64, 0x9e985bf4, 0x5b7b885c, 0x0b1b6a90,
0x445cb520, 0xe2ff9975, 0x294c23b1, 0x1abbd21a, 0xe461e3d8, 0x7274020d, 0x69b7e2e7, 0x2ef3614d,
0x7743c977, 0xcbcfd022, 0x9ecaae13, 0x5b0f9715, 0xa09791eb, 0x153fc68d, 0x0eb044b9, 0x7588ff16,
};
}
internal class ImoutoStyleCrypt : CxEncryption
{
public ImoutoStyleCrypt () : base (0x278, 0xd7)
{
PrologOrder = new byte[] { 2, 1, 0 };
OddBranchOrder = new byte[] { 1, 2, 4, 0, 5, 3 };
EvenBranchOrder = new byte[] { 7, 5, 1, 3, 6, 4, 2, 0 };
}
protected override uint[] ControlBlock { get { return ImoutoControlBlock; } }
static readonly uint[] ImoutoControlBlock = new uint[] {
0x9c91badf, 0x8b8f868d, 0xdf919096, 0x8b91909c, 0xdf93908d, 0x9c90939d, 0xd2d2df94, 0x9e8bacdf,
0x9e9c968b, 0xdf869393, 0x9bdf8d90, 0x929e9186, 0x939e9c96, 0xdfd38693, 0x9a8d969b, 0x86938b9c,
0xdf8d90df, 0x969b9196, 0x8b9c9a8d, 0xdfd38693, 0x91968c8a, 0x978bdf98, 0x8fdf8c96, 0x8d98908d,
0x9edf929e, 0x90d09b91, 0x939ddf8d, 0xdf949c90, 0x92908d99, 0x978b90df, 0x8fdf8d9a, 0x8d98908d,
0xdf8c929e, 0x93939688, 0xdf9a9ddf, 0x9a939396, 0xdf939e98, 0x8bdf869d, 0x93df9a97, 0x919a9c96,
0x9edf9a8c, 0x9a9a8d98, 0x8b919a92, 0x4e7ddfd1, 0x897c337d, 0xb07c727c, 0x7f7c767c, 0x8a7c1d7d,
0x9d7c727c, 0x0f7db17c, 0x3c6fbe7e, 0x3a7db66c, 0x157d5f7d, 0xb66c516c, 0x5f7d3a7d, 0xbe7e157d,
0x256f436d, 0x3a7db66c, 0x157d5f7d, 0x256f2b75, 0x3a7db66c, 0x157d5f7d, 0x436ebe7e, 0x897c337d,
0xb07c727c, 0x7f7c767c, 0x187d567d, 0x5d7d8f68, 0x4e7d167d, 0x327d397d, 0xbc7c767c, 0x6c7ca57c,
0x367da77c, 0x177d197d, 0x497d2974, 0x157d187d, 0x5d7d3b7d, 0x487d237d, 0x7ef5bd7e, 0x69d6bc96,
0x7ca77c7a, 0x7cbc7ca1, 0x72586f74, 0x77307713, 0xdf10760a, 0xcececfcd, 0x4473f5f5, 0x056c1c6e,
0xbe7e8469, 0x916da169, 0x8c6c046a, 0xbd7e8c71, 0x727e72f5, 0x7d39761d, 0x7dbe7e32, 0x7da57357,
0x7d1e7d40, 0xca397d0e, 0x337d936f, 0x557d7a69, 0x217da570, 0x39761a6e, 0xbd7e4f6e, 0x5f7df5f5,
0x056c167d, 0xbc75be7e, 0x3a7db075, 0x69719b71, 0x487d0f7d, 0x4368167d, 0x567d9a6f, 0xbe7e187d,
0x0e7d377d, 0xb67e397d, 0x73577df5, 0x7d407da5, 0x770e7d1e, 0x7db07537, 0x77ac6e32, 0x75bc750a,
0x77367db0, 0x7da57025, 0x7d377d4a, 0x7e5d7d4c, 0x397df5b6, 0x577d337d, 0x4a7dbd6d, 0x547d557d,
0x337d427d, 0xbd7e417d, 0x346cf5f5, 0x337dad6e, 0x85760777, 0x166f4a7d, 0x367d4173, 0x1d727e72,
0x327d3976, 0x646e1a6e, 0x367d537d, 0xf5f5bd7e, 0xa573577d, 0x1e7d407d, 0x337d0e7d, 0x50689c71,
0x7edf327d, 0x7d956d8a, 0x774a7d41, 0x6a936f15, 0x7d187d16, 0x7d4a7d4a, 0x7d1f7d3b, 0x725d7d5d,
0x7d78725f, 0x7d417d5d, 0x7e187d56, 0x417ddf89, 0x5b7d447d, 0xa37e3a7d, 0xf5f5a37e, 0x557d417d,
0x4e7dbe7e, 0x367d157d, 0x3e7d5d72, 0x337d427d, 0x6fca327d, 0x69337d93, 0x7d427d7a, 0xf5bd7e40,
0x7d7a69f5, 0x7d407d42, 0x77ac6e32, 0xf5be7e0a, 0xa573577d, 0x1e7d407d, 0x557d0e7d, 0x417dbe7e,
0x417d5d7d, 0x417d5d7d, 0xa47ea47e, 0x5d7da47e, 0x547d487d, 0x7df5667e, 0x7d3e7d41, 0x7d567d42,
0x7d3a7d18, 0xf5bd7e48, 0x73577df5, 0x7d407da5, 0x7d0e7d1e, 0x69056c0f, 0x7d367d84, 0x7d397d2f,
0x7d9c7117, 0x7d3b7d4a, 0x7d527d57, 0x7d507d12, 0x7d327d36, 0x7d567d5d, 0x7e5d7d37, 0x7b71f5be,
0x9c711f7d, 0xb67e167d, 0x7d5f7df5, 0x7d4a7d42, 0x7d9c7155, 0x7e337d16, 0x397df5b6, 0x7d936fca,
0x7d7a6933, 0x7e127d55, 0x7e127da4, 0x7d547da4, 0x7da47e1e, 0x7e1e7d54, 0x6e337da4, 0x7d646e1a,
0xf5bd7e53, 0x7d487df5, 0x7d427d3e, 0x7d0e7d1f, 0x7d337d41, 0x7e597d48, 0x577df5be, 0x407da573,
0x0e7d1e7d, 0x577d337d, 0x9d675d6f, 0x397da873, 0x3b7d4a7d, 0x397d2f7d, 0x417d177d, 0x056c507d,
0x367d8469, 0x3e7d9c71, 0x1f7d3b7d, 0x5d7d5d7d, 0x397d4e7d, 0xb67e367d, 0x447df5f5, 0x3b7d4a7d,
0xb16dbe7e, 0x9c71557d, 0x337d167d, 0xb77e567d, 0x7d387df5, 0x7d7a6933, 0x7d9c7155, 0x7e567d16,
0x327df5b7, 0x577dbe7e, 0x407da573, 0x0e7d1e7d, 0x7773557d, 0x167d207d, 0x397d4e7d, 0xbd7e367d,
0x327df5f5, 0x4a7d427d, 0x9c713b7d, 0x427d3e7d, 0x397d7a69, 0xa573577d, 0x1e7d407d, 0x337d0e7d,
0xa8732975, 0x5d7d327d, 0x427d3e7d, 0x387d5d7d, 0x377d5b7d, 0x337d167d, 0x4a7d3a7d, 0x5b7d1a7d,
0xb77e567d, 0x917cf5f5, 0x987ca47e, 0x747c8b7c, 0x977cba7e, 0x907ca17c, 0xba7ea17c, 0x767c7a69,
0x667e8a7c, 0x987ca77c, 0x757ca47e, 0x337da47e, 0x7469b575, 0x487d3a7d, 0xf5f5b67e, 0x9c7e9c7e,
0x3e7d5f7d, 0x8168be7e, 0x177d5c6d, 0x577d377d, 0x407da573, 0x0e7d1e7d, 0x61691f7d, 0x337d546e,
0xa47e917c, 0x7f7c737c, 0xa47e747c, 0x1f7d987c, 0x167d5f7d, 0x187d567d, 0xb67e347d, 0xbdbc72f5,
0x45cebcd0, 0xbbd86f7c, 0x0c89acb3, 0x719234f9, 0x500456ec, 0xbf9c5033, 0xc5cdeb7c, 0x57776569,
0x15759c7e, 0xce764abc, 0xb08f0f38, 0x02fd9979, 0x01c1c1d8, 0xb3a0450c, 0x3ad2e0ad, 0xf282a28b,
0x9d4da002, 0x45f7fdc1, 0xa6ac2c9a, 0x8daf7a97, 0xffa843df, 0x0c2a8f16, 0x271c25e9, 0x22164799,
0xa92332a7, 0xdeef4be3, 0x28e596a8, 0xe42833b1, 0x87e9d493, 0x3727307e, 0xc4360c52, 0x141a1c55,
0xb2eebdf8, 0x989f9528, 0x2ebfdb1c, 0x72641c8f, 0x0e362bc2, 0x4fae1791, 0xc8ab8f0e, 0x8fa115ee,
0xada212d8, 0xdac32301, 0xec18485d, 0xbc8ce6f5, 0x79962be5, 0x69814c94, 0x96efead6, 0x69e8e3be,
0x3a6e7485, 0xead7bf5b, 0x04ea533e, 0x887470a5, 0x552f91b3, 0x975f44cc, 0x7ad282d4, 0xf6d9b38c,
0xe76f1cfd, 0xf5706c21, 0xefeccf0e, 0x849dd4c9, 0xade2474f, 0x1b45f369, 0x7e21976e, 0xa10c9eca,
0x2d5d85f7, 0x6accdbd8, 0x65d2bb19, 0x8c325bbc, 0xb90ef4f4, 0xcc18b595, 0x19649633, 0x8341d8d7,
0x2f195257, 0xa0ed9621, 0x1d7953c5, 0xf7daa4c1, 0x9bbcea5f, 0x30aed22a, 0x9c91a871, 0xb368800c,
0x1016536e, 0x9cb72499, 0xe46d7de4, 0x977ccf49, 0xb1f2a544, 0x4c4493d8, 0x950972b2, 0x7169b541,
0x9ceec5b7, 0xde848c5a, 0x85e34c07, 0x6f184730, 0xc8a2e2c6, 0x1c072811, 0xdee6885a, 0x1c6c7fb8,
0x8b597fe9, 0x9412a96a, 0x0b0f42e8, 0x6557e34e, 0x861905b3, 0x4c0c2dff, 0xad4462f9, 0x8ab4d260,
0x537b147a, 0xd35f0ac9, 0xd85f457d, 0xa62616f9, 0xfda1d245, 0xf028be7b, 0x9317fd1e, 0x242d9f12,
0xd532263a, 0x7296f576, 0xbce041fb, 0xf354bc22, 0x7cbf3560, 0xddda6048, 0x9fbebcc0, 0x6b034357,
0x9c5d00d3, 0xb1792e0b, 0x42f68570, 0xa9a6b353, 0x0e67dad9, 0x023c04d5, 0x8b187287, 0xf94b051e,
0xb332cc2e, 0xfb8c65bb, 0xe40553c7, 0x36c6bf95, 0x7a74e52c, 0xe5a6497d, 0xfb5c9bff, 0xabd7abd8,
0xcdd35cf0, 0x6b4ab439, 0x43ab6526, 0x019bc4ee, 0xf332b913, 0xa06c7649, 0x52af60ba, 0x1477e66f,
0xbee3c1e7, 0x825fe633, 0x81f3b272, 0x8e3c104d, 0x0956e686, 0xc58c13ab, 0xae01266f, 0x87d551b9,
0xfe2ab79f, 0x039d6ac1, 0xeaa3ddb8, 0x8ad73c9f, 0x3401d424, 0x0132d093, 0x1932ff32, 0x713585ba,
0x0b73d762, 0x1988732a, 0x3480e775, 0x23d9e24c, 0xad41997d, 0x2f838c6c, 0x7876d7d4, 0x5a1b885e,
0xd5c0e254, 0x9cccdb9e, 0xd42778cd, 0xafaaf2db, 0xe61008ca, 0xa566900e, 0x9e8648e4, 0x58047ac1,
0xd0322bf3, 0x92112b4b, 0x2bd479a5, 0xf05f0c69, 0x3f22edb2, 0x665990fe, 0x98507599, 0x7e1ce769,
0x49c33e7b, 0x6a3e565b, 0xf37bfd1c, 0x6838ba13, 0x71ac8605, 0x5f854028, 0xafb1c299, 0xf738570a,
0xe76c4166, 0xd1d5bb14, 0xd411c2ae, 0x8120f274, 0xa4892784, 0x3d543dab, 0x6af3ab34, 0x9d2a1040,
0x1fe14b56, 0x5e8036d6, 0xb334c47e, 0x527f288e, 0x3bc560e5, 0x1448108c, 0x3c4a1978, 0xc6810326,
0x24c0e9dd, 0x57ac0eff, 0xaeaf2bb4, 0x21fc89e2, 0xd49383e3, 0x278f3ecf, 0xf1d7f02e, 0xf4e87a53,
0x81659a34, 0xfc2a7769, 0x22f947db, 0x18d6f29e, 0x7bd778cc, 0x34e63b74, 0x4327837b, 0x43b23f4a,
0x2faaf555, 0x080f21d8, 0xd883ab31, 0x28f7e548, 0x961e15de, 0x27b56217, 0xa9313edf, 0x4c75e7ba,
0x9441cc74, 0xe617288f, 0xf2fe905a, 0xa58a2a26, 0xc770ac96, 0x057c8dee, 0x042bca16, 0x35ad73bb,
0xbefb0221, 0x989b124b, 0x0183dcfb, 0x93a22db8, 0x7e964b97, 0xff7d84ad, 0x61468d1c, 0x41c58016,
0xbd6022c7, 0xcfafe4e6, 0xd04c6664, 0x71c039ac, 0x08bf2e43, 0x4672f5d3, 0xcc5d8794, 0x4a1345fc,
0xc9fd140f, 0xb8678dd4, 0x1867e8bd, 0x6c4ec398, 0x878ab83a, 0x02c2900e, 0xf97cf590, 0x6c5a671b,
0x8681ecdc, 0x2bfd1a87, 0xbb65a1ee, 0xcbf781c2, 0xa2013ff6, 0x8c026ee2, 0x8ad5524c, 0xfa46551f,
0xd5507bbf, 0x6a5d00ee, 0x1a60b69b, 0x4edeceda, 0x25992ecc, 0x236fc615, 0x8fcab1c1, 0x084380cf,
0xd3723c02, 0xfa1bb4e0, 0x41703b91, 0xc884373d, 0x4db4af4c, 0x4876b7d6, 0x3e6663a5, 0xc3372d5a,
0x8af05730, 0x43f96565, 0x280870dd, 0x258300b2, 0x0f1ff948, 0xe5addfbe, 0xd133f857, 0xf2b45133,
0xddbfe3ab, 0xe0e3706d, 0x3235bd77, 0xe9b6effe, 0x1fe4ef36, 0x8fd89928, 0x27279626, 0xeb799df0,
0x1e2d5bb4, 0x64415ae5, 0xefc24d6e, 0xda6fb0e3, 0x1c8a4ece, 0x8ab56b95, 0x0e91d30a, 0x02ef3eea,
0xd9073f45, 0x113c6ab7, 0x6c77bf54, 0xa52f90bd, 0x01f280b4, 0x83c1b5f7, 0x423d4069, 0x22adcd65,
0x58537598, 0x91930d6a, 0xdff6a6b3, 0x287243d2, 0x33e92ca2, 0xe593d4e6, 0x2636aad3, 0x64f5fe3c,
0x4f875310, 0xceb3e06c, 0xedcdab02, 0xb872fd7a, 0xd7baa454, 0x866ba43c, 0x9e6e8bc5, 0xdf04f14b,
0x5081a7fe, 0x1cc6eaef, 0xf657b595, 0x29012cf3, 0x4a58e4ff, 0x694dd93c, 0xb74938e8, 0xd457436a,
0x560eafdc, 0x2ce09ec8, 0x465de8e9, 0x7ca0ec1b, 0xd93829c7, 0xbca12446, 0x6b60b1a0, 0x9f027d58,
0x9ab391e3, 0x9853ec40, 0x527e834a, 0x198c317a, 0xf985d777, 0x988fb533, 0xefcf3410, 0x9ac81387,
0x93f87488, 0x3b1eb146, 0x12dbb1b0, 0xab1cef83, 0x9e8c014c, 0x56eb135d, 0x35097903, 0x2aa776d0,
0xefba659b, 0xd8576489, 0xa44e176c, 0xf5d417a8, 0x66f0a62b, 0xb7a4f687, 0x1d6f27b4, 0xd30983b9,
0xcdc46346, 0x605567a2, 0x944f9b8e, 0xd3456f55, 0x0d542ee5, 0xa8e34d20, 0x5fdefe07, 0x2fc58135,
0x26e09472, 0xbe691ac6, 0x5aafcbe2, 0x322d4063, 0x77148178, 0x15d30784, 0x21de79cd, 0x999c36b1,
0xdd31ccc4, 0x5c9019a7, 0x98be930e, 0xfb604ed7, 0x0bfcef1f, 0x9544feba, 0x45a65682, 0x240e539b,
0x13451d89, 0xcdf37d73, 0xf1548863, 0xb075b59f, 0x554038cf, 0x28372884, 0x68136660, 0xa51373f7,
0xd87941d0, 0xc3694841, 0x2ecbff33, 0x807c415a, 0xd10347ab, 0x0ed7e4e5, 0x16363adc, 0x89d33036,
0x6016a160, 0x19f19a5a, 0x8956c6b7, 0x1731780f, 0xb4212ec0, 0x72fa92b6, 0x33c32348, 0x56d08e8a,
0xe4be93dd, 0x2739fe6d, 0x2541e828, 0x4daedcc3, 0x7376c3c8, 0xd9f44afe, 0x9272061d, 0x23f7aeca,
0x429152c7, 0xc2697d28, 0x51179d67, 0x62735ef7, 0x6d37d2eb, 0xb55655c3, 0xbfb33ada, 0x02839c8f,
0x49ea2059, 0x6be959b5, 0xda6278b4, 0x5a538796, 0x5c8497f8, 0x36499ff2, 0x85620f5e, 0xa11be0dc,
0xb113a10d, 0x0d398359, 0x3802b809, 0x1e8b4d3a, 0xe67de6af, 0xc3235a27, 0x1bc9930d, 0xd740c0cd,
0x5e3e6b85, 0xd2054645, 0x4d44571e, 0x4532a3e6, 0xeee9d279, 0x87fbde6b, 0x609c8075, 0x7b21adfd,
0x320b8d52, 0xccb86869, 0xbbc67e56, 0x138cb7cd, 0x94422afb, 0xc2cdb1bf, 0x35fbeafd, 0x0f98f183,
0xb985532f, 0xbea5b0da, 0x8d8ffe7f, 0x37d8e708, 0x6325d619, 0x510745a4, 0xa275914a, 0xaf7bd793,
0xed263795, 0x93dfbc22, 0x7a7f9995, 0x1d1665b2, 0x90b2fde0, 0x20fe2705, 0x4e80f43e, 0x745ca349,
0x019e0c38, 0x532456ef, 0xb876f67e, 0x9b2a66de, 0x5043034b, 0x16c5507b, 0x09d1bb96, 0x0439f550,
0x18a1d128, 0x824a0731, 0x258fc0ce, 0x36ec993f, 0x80cf64fe, 0x356c8638, 0xa39bbbb9, 0x22ffeac0,
0x7d39c4d0, 0x32e95341, 0x8d0187d3, 0x6c99079f, 0xec240adc, 0xa9af8c5a, 0x94b8065e, 0x28009b4a,
0xfa5b4c58, 0x8f12a9e1, 0xa95ecd98, 0xe9603646, 0xcc12dc04, 0x50f5fd0f, 0xc334d966, 0x32d07ccd,
0x8300fca5, 0x6001e499, 0x5b838ad5, 0xf5562cca, 0x30232d6f, 0xed01a56f, 0xd1409b8d, 0x137efc62,
0xabc2a7c7, 0xab208ec1, 0x841ef72d, 0xd152c5ec, 0xe81bb7f3, 0x850187aa, 0x9c40f47d, 0x5ff50c62,
0x2b724688, 0x2e8557e4, 0xb135f8ed, 0x4fa38d46, 0x0f3eb921, 0x847159f2, 0xefbeb40a, 0x4339f17f,
0xbf8483f2, 0x6770b2d8, 0x576acb52, 0xda464833, 0x9d295648, 0x86ba73f3, 0xbe44d7c4, 0x868c2115,
0x9aecc2ea, 0x3fce381f, 0x5d4bdac2, 0x7863bbf7, 0x6395a2e2, 0x209c7342, 0x7d9718fb, 0x7f2f4b02,
0x6edc122d, 0x7a39b294, 0xd0a34d11, 0x6d4d9472, 0xb1775b56, 0x66099ca5, 0xc898dba5, 0xff094e89,
0x49eee138, 0xc74554d4, 0xbebb78bd, 0x68069f7f, 0xd143e934, 0x16ea614a, 0x5b03b028, 0x7433b06e,
0x112ac5c4, 0x93c63bb1, 0xddb35880, 0x45398ff9, 0x8a14734a, 0x09e8208e, 0x18109716, 0xf73db871,
0xad841334, 0xb77606af, 0x539aaa53, 0x5b3f9aa2, 0x81b7cd23, 0x4795a0b6, 0xe534763a, 0x1d76556b,
0x7c5c9a58, 0xb7003bec, 0xfd4c55d8, 0x7d9bac3c, 0xb11ef2f5, 0xd17229b8, 0x4e20b59f, 0x274aa421,
0x5cfd682d, 0x13794dee, 0xaa0feb1e, 0xab4e6384, 0x67ef1f62, 0x25686df1, 0x4c0222aa, 0x744c2e19,
0x561f35e9, 0xf8e22c4c, 0x4f863ce0, 0x4f15b253, 0x2bf4b937, 0xf09e873e, 0x96627d1a, 0x5b51e77e,
0x10e61481, 0xfd28b58a, 0xe34fc314, 0x12160d1b, 0xddf8d02f, 0xc56b1376, 0xce64ae6c, 0x4295c0ed,
0x58b1c5c7, 0xf7f5adc3, 0x03c5a5a0, 0x8769e34d, 0x4e01b5b0, 0x793a96dd, 0x4169c9db, 0xadc496aa,
0x7d5dc5e4, 0x286d5a0f, 0x6c307a00, 0x9e8a7f57, 0x8880e20b, 0x4938b163, 0x3acea0cb, 0x36f331ba,
0xf66f3c41, 0xfa626b07, 0x0541bb30, 0xb0b72590, 0x83542c3f, 0xd00c7261, 0x2d9b31dc, 0xb8a6d50b,
0x2a1e7c82, 0x8752abdc, 0x3498e8a6, 0xd7da1c7e, 0x5f451585, 0x13896231, 0x7e8623ec, 0x47c934a6,
0x38c898f7, 0xd265d1a8, 0x563fe6c7, 0x94f4fe90, 0xbf8bdb54, 0xd62f47a5, 0xfaeedc35, 0xb6076992,
0xfe7acb2b, 0x1c7012c9, 0xc82c8820, 0x18c81963, 0x6ac638cc, 0xc728e32e, 0x1931ef4b, 0x7287bf52,
0xc569fde8, 0x12f65cc0, 0x44c44e2e, 0x8d907180, 0xca04d47e, 0x404d63d6, 0x5499167d, 0x039a27d4,
0xb1cb5251, 0x0b231cd2, 0x5b536196, 0x4c350a6a, 0xee0eef22, 0x966f1225, 0x4b474c5b, 0x7fbfd5b3,
0xd3101a66, 0x0dcfa92b, 0x6de5ab3b, 0x974c54a3, 0x69ac86de, 0x1d1f241f, 0x8c5f359c, 0xf9a024f5,
0x784302e2, 0x86d17895, 0x17820cbd, 0x6e955717, 0xc27ea685, 0xd4084ab2, 0xe13c54e7, 0x9c131d1d,
0x284be1be, 0xa4bae6d4, 0x515ad718, 0x3cfc0b5e, 0x049005d4, 0xd580a4c9, 0x00a7540a, 0x431bb5a8,
0x5b8ccb1e, 0x0086d12b, 0xfecef3a1, 0x9899627d, 0xde70b335, 0xe41b39cf, 0xfc562045, 0xc2354b34,
};
}
internal class ComyuCrypt : CxEncryption
{
public ComyuCrypt () : base (0x1a3, 0xb6)
{
OddBranchOrder = new byte[] { 4, 3, 2, 1, 5, 0 };
EvenBranchOrder = new byte[] { 0, 7, 5, 6, 3, 1, 4, 2 };
}
protected override uint[] ControlBlock { get { return ComyuControlBlock; } }
static readonly uint[] ComyuControlBlock = new uint[] {
0x9c91badf, 0x8b8f868d, 0xdf919096, 0x8b91909c, 0xdf93908d, 0x9c90939d, 0xd2d2df94, 0x9e8bacdf,
0x9e9c968b, 0xdf869393, 0x9bdf8d90, 0x929e9186, 0x939e9c96, 0xdfd38693, 0x9a8d969b, 0x86938b9c,
0xdf8d90df, 0x969b9196, 0x8b9c9a8d, 0xdfd38693, 0x91968c8a, 0x978bdf98, 0x8fdf8c96, 0x8d98908d,
0x9edf929e, 0x90d09b91, 0x939ddf8d, 0xdf949c90, 0x92908d99, 0x978b90df, 0x8fdf8d9a, 0x8d98908d,
0xdf8c929e, 0x93939688, 0xdf9a9ddf, 0x9a939396, 0xdf939e98, 0x8bdf869d, 0x93df9a97, 0x919a9c96,
0x9edf9a8c, 0x9a9a8d98, 0x8b919a92, 0x4e7ddfd1, 0x897c337d, 0xb07c727c, 0x7f7c767c, 0x8a7c1d7d,
0x9d7c727c, 0x0f7db17c, 0x3c6fbe7e, 0x3a7db66c, 0x157d5f7d, 0xb66c516c, 0x5f7d3a7d, 0xbe7e157d,
0x256f436d, 0x3a7db66c, 0x157d5f7d, 0x256f2b75, 0x3a7db66c, 0x157d5f7d, 0x436ebe7e, 0x897c337d,
0xb07c727c, 0x7f7c767c, 0x187d567d, 0x5d7d8f68, 0x4e7d167d, 0x327d397d, 0xbc7c767c, 0x6c7ca57c,
0x367da77c, 0x177d197d, 0x497d2974, 0x157d187d, 0x5d7d3b7d, 0x487d237d, 0xbcf5bd7e, 0x8d868f90,
0x8b979896, 0xdfd6bcd7, 0xc6cfcfcd, 0xa83a74df, 0xacb4adb0, 0x93bedfd1, 0x968ddf93, 0x8c8b9798,
0x8c9a8ddf, 0x9a898d9a, 0xf5f5d19b, 0x4b768a7e, 0x407d427d, 0x9f7c327d, 0x7f7ca47e, 0xbd7e417d,
0x7dbf7ef5, 0x7d397d42, 0x73576959, 0x7d367d71, 0x7d326c32, 0x7d377d56, 0x6a2b755d, 0x7d3a7d40,
0xf5bd7e1f, 0x6768bf7e, 0x337dae75, 0x896d1577, 0x74733a7d, 0x3d7d2e7d, 0xbd7e527d, 0x76bf7ef5,
0x744269a1, 0x6e506c5b, 0x7d377d33, 0x6f357d18, 0x74496e49, 0x6e506c5b, 0x7ea37e33, 0x7ea37ea3,
0x72f5f589, 0x718e6e7d, 0x6ca96f8c, 0x7eac6f8c, 0x6973f5bd, 0x397d646e, 0xb67c937c, 0x337d6c7c,
0x3b655165, 0x5f7d3a7d, 0x1669167d, 0xa775337d, 0xbe7e367d, 0x3d7d1577, 0x9f6c337d, 0x557d1f6f,
0x3e7d5f7d, 0xbd7e427d, 0x447df5f5, 0x327d157d, 0x1669be7e, 0x397d4d7d, 0x5b7d3376, 0x337d4973,
0xaf6a3376, 0x5270987e, 0x7ebe6870, 0x6c337d97, 0x6c8c718c, 0x7e1f6f9f, 0x7df5f5bd, 0x76337d44,
0x7d4269a1, 0x7e166933, 0xf5a37ea3, 0x7d4a6cf5, 0x7d796d33, 0x7d447336, 0x7e167d15, 0x70527098,
0x977ebe68, 0x4e6c367d, 0x157d567d, 0x6ff5be7e, 0x714e6e25, 0x7d397d2d, 0x753b7d4a, 0x7d3e6f90,
0x6f427d4a, 0xdf9e676f, 0x936f3a74, 0xbe7e327d, 0x658f6bf5, 0x6d337d2f, 0x733a7d47, 0x7d926d56,
0x7e357d18, 0x69506c98, 0x7d977eba, 0x7d407d42, 0x76907039, 0x7e5b7d10, 0xf5f5f5bd, 0x786d8a7e,
0x497d2b75, 0x377d1e7d, 0x337d5d7d, 0x897eb77e, 0x836dbf7e, 0x72df3276, 0x7e707098, 0x6f987ea1,
0x7d9f744c, 0x6a5e6933, 0xf5977e04, 0x6c8a7ef5, 0x74547d99, 0x7d557dbc, 0x7d167d48, 0x6f387d26,
0x708b703d, 0x7e5d7db3, 0x68bf7e89, 0xdf2b76b2, 0x1e6fa16f, 0x987ea17e, 0x447d5b7d, 0x547d3d7d,
0xf5f5977e, 0x7e6e8a7e, 0xbe74527d, 0x427d177d, 0x197d5d7d, 0x597d347d, 0xbf7e897e, 0x056c8b70,
0x70df6b6a, 0x7ea17e8b, 0x7caa7498, 0x7cbc7c7e, 0xf5977e97, 0x7c8a7ef5, 0x6ca87c97, 0x7d227d5a,
0x7d557d1d, 0x7d427d3e, 0x7dba7118, 0x7e437d48, 0x77bf7e89, 0xdf0d6e36, 0xa17e746b, 0x9f7c987e,
0x8c7c6c7c, 0x977e767c, 0x70f5f5f5, 0x7d207d76, 0x7690703b, 0x7d3e7d10, 0x936fca42, 0x2b75337d,
0x327d367d, 0xb968be7e, 0x1f7d1170, 0xb26fbe7e, 0x1f7d7568, 0x4276be7e, 0x377d1f7d, 0xbd7e5d7d,
0x417df5f5, 0xbd7e557d, 0x6fcaf5f5, 0x6f337d93, 0x714e6e25, 0x7d567d2d, 0x7d377d18, 0x70987e16,
0x7e9c6da8, 0x7cad7c8c, 0x7e7a7c81, 0x7d977e8b, 0xf5be7e32, 0x0f7d3268, 0x127d7872, 0x167d467d,
0x397d4e7d, 0xbe7e3a7d, 0x1a6e6f74, 0x987e377d, 0x337d8372, 0x576a0976, 0xbe7c8c7e, 0xa17c907c,
0x8b7ea47e, 0x0f7d977e, 0x337d2c77, 0x237d237d, 0x7f6e367d, 0x4e7d167d, 0x557d397d, 0xa36b3d76,
0x377d367d, 0xbd7e167d, 0x4271f5f5, 0x337d6a72, 0x907cbe7c, 0xa47ea17c, 0x907c987e, 0x727c8d7c,
0x977e6c7c, 0x256f397d, 0x4c7d4e6e, 0xbe7e157d, 0x1a6e5274, 0x4c68377d, 0x3268337d, 0x17710f7d,
0x4a7d367d, 0x447d427d, 0x056c337d, 0x187d567d, 0x74f5be7e, 0x7d936f3a, 0x7d407d42, 0x7db06e33,
0x7db46936, 0x7e167d15, 0x7e8d72be, 0x7d4a7da7, 0x6c0e6b54, 0x7e127005, 0xf5f5f5bd, 0x0f7d4c68,
0x5b7da06e, 0x576a0976, 0x407d427d, 0x466fbe7e, 0x9271ad74, 0x7768337d, 0xbe7eb469, 0x4a7d447d,
0x9a6b3b7d, 0x337d5b76, 0x576fad73, 0xa37ea37e, 0x7df5f5f5, 0x7d157d44, 0x936fca32, 0xbe7e0f7d,
0x926d936f, 0x357d157d, 0xad7c987e, 0x7a7c817c, 0x5d6f337d, 0x8c7eba75, 0x817cad7c, 0x937c7a7c,
0x987c9d7c, 0x977e8b7e, 0x397d297d, 0x3e7daa68, 0xbd7e427d, 0x447df5f5, 0x3b7d4a7d, 0x936f3a74,
0x926d327d, 0xbd7e167d, 0x7d3268f5, 0x6e327d36, 0x7d61701c, 0x68b46a55, 0x7d417d89, 0x7e427d3e,
0x7cf5f5bd, 0x7c907cbe, 0x7da47ea1, 0x7d3a6955, 0x7d397d2b, 0xf5be7e54, 0x4e6e256f, 0x157d4c7d,
0x987e427d, 0x9c6da870, 0xad7c8c7e, 0x7a7c817c, 0x977e8b7e, 0x237d1f7d, 0xbe7e427d, 0x2b7d3a69,
0xf5f5bd7e, 0x7d447df5, 0x69a17633, 0x69337d42, 0x7ea37e16, 0xf5f5f5a3, 0x0f708c6a, 0x367d6268,
0x557d8e73, 0x427d157d, 0x936f3a74, 0xbe7e327d, 0x72987ef5, 0x69337d6a, 0x7e68707d, 0x6c1b6b97,
0xdfbb6f21, 0xac7cb57c, 0x337d7e7c, 0x0f7d3268, 0x177d2771, 0xbe7e3b7d, 0x7d237df5, 0x7d567341,
0x755d6f35, 0x68367dba, 0x73407d58, 0x7d567d03, 0xf5bd7e5b, 0x8a7ef5f5, 0x157d447d, 0x1f7d3a7d,
0x427d4b76, 0x327d407d, 0xa47e9f7c, 0x417d7f7c, 0x7ef5bd7e, 0x7d427dbf, 0x76597d39, 0x7d427d4b,
0x730f7d40, 0x7d517d8e, 0x7e557d33, 0x7d4e7dbe, 0x7d837233, 0x7d447633, 0x7d576a50, 0x7d507d41,
0x7d397d41, 0x7d3b7d4a, 0xf5897e1f, 0x466cf5f5, 0x397d4476, 0x68707d69, 0x6fcb397d, 0x6d337d93,
0x7e2b7578, 0x7cad7c8c, 0x7e7a7c81, 0x7e337d8b, 0x7d486dbe, 0x7d48685d, 0x7d917155, 0x7e167d23,
0xf5f5f5bd, 0x7ea37ef5, 0x7d4c7da3, 0x72be7e5f, 0x7d16695e, 0x7d577d33, 0x67537d39, 0x7d0f7d9d,
0x7d497d32, 0x7d197d20, 0x22c3f55b, 0x1fe1bca5, 0x296d327f, 0xbf4655bb, 0x271bfd84, 0x9dc9f775,
0x6a396019, 0xbb316b08, 0x7d4ccbf5, 0xef612dc2, 0x4e7cb1a1, 0xefc091a2, 0x0c4095b7, 0x4dcd0f8f,
0x09fe386e, 0x8f83fce6, 0xaf8b737b, 0x4db8803a, 0xc7d3e004, 0xedd446ee, 0xe18f337f, 0xb467401c,
0x11c025fa, 0x0ed6322f, 0x7f493793, 0xa2b52008, 0x35a038c4, 0x4a640e05, 0xe9b611d3, 0x26fa62ce,
0xcef2d932, 0xa2f2ba50, 0x2fcac91c, 0xbcd22555, 0xa02a089a, 0xacbc800e, 0x550f8e29, 0x62c73a93,
0x897f08c6, 0xf3799463, 0x6fd0cc73, 0xed4411f4, 0x7e2321fb, 0xaad6aec5, 0x036078b2, 0x25494cd5,
0xc2d3bfd1, 0xd5ea81fc, 0x0886894d, 0x6cff2667, 0x41fccddb, 0xd396d716, 0x2a9d5a09, 0xe638827b,
0xadf4635c, 0xc6003fef, 0x31454acc, 0xe1500dda, 0x46cf53d5, 0x750cd529, 0xfda3aa39, 0x4b7877a7,
0x53d05d5a, 0x01332627, 0x1dd10160, 0x9e609da4, 0xd6f5a7b6, 0x8b382dc0, 0x004d88b4, 0x545a4018,
0xba980aaa, 0xeea43a3d, 0xb91b3fe4, 0xa0965c99, 0x3731d8f0, 0xe8c0644a, 0x9e72955e, 0xab59a0e7,
0x6b23cb98, 0x1fe4fad6, 0xa37f3f8e, 0x2214b7cb, 0x9c621ea9, 0x8d89f543, 0xe0d49701, 0xb9ac412a,
0x403925dd, 0xe42d1546, 0xcf873ac1, 0x0aa7dae5, 0x21e332aa, 0x39378fd4, 0xbae1f8d7, 0xe2498f35,
0x16c9c11c, 0xb8a652f7, 0x2fa5130b, 0x1a0a5cbf, 0x608d77c0, 0xd313f4bd, 0x9df44553, 0xf8005ec4,
0xc8816b32, 0x41a1f393, 0xb44a9a77, 0x402201bd, 0xe0a33bf0, 0xf05a98fe, 0xe59490e9, 0x34fc3083,
0x057cf4ff, 0x63afcc41, 0xa6e5db4c, 0xa6c33972, 0x109409ab, 0x63ed6914, 0x5b339232, 0xd0a43407,
0x306e5208, 0xae194901, 0xcdcb1d3d, 0xf1695d07, 0x5f3b59d0, 0xa921d2a4, 0xc43e6ffa, 0xf09d7f22,
0xe2086b83, 0x0c887070, 0xed0395e8, 0x854d8765, 0xa770cc28, 0x686f3803, 0xd12289b4, 0x55376b55,
0x347ae04d, 0x13cd8867, 0x21fcd359, 0x6f6838a2, 0x5d878268, 0x081230b0, 0x4e650001, 0x27feb637,
0x2a5a0d75, 0x98b98e8a, 0x37a3d205, 0x9bd9a16b, 0x626f4633, 0x1aff66d5, 0x73775d2d, 0x943acf9f,
0x63bfbdae, 0x690441be, 0xb461c91f, 0x1c31ec2f, 0x15b44e96, 0x5a88b44a, 0xf50a5482, 0x2b90d060,
0x6aed13b0, 0xc367c97e, 0x9aba2ed8, 0xc628c155, 0x0e5cbe5a, 0x41277292, 0x43f59984, 0x3f7e3bf8,
0x487e1fe9, 0xfb462b23, 0xda4f6038, 0x9764f5f1, 0x15ec6247, 0x7659232c, 0xcdd0bb54, 0x5bc0d691,
0xefcc30e6, 0xa35e5432, 0x7dbb9ab6, 0x3937f5c4, 0x49d309fd, 0x477e3255, 0x69a0206f, 0x2850cb81,
0x406ecd8c, 0x8e2af5ac, 0xf8175347, 0x91615d3a, 0xc9ac2788, 0xf57b4d62, 0x0e7f004d, 0xb9d0f4cb,
0x15a46dc1, 0x24e323d0, 0x40690307, 0x0218c53a, 0xae7f20f6, 0x25dc07d6, 0x1a8a4d22, 0x9ed1266b,
0xb8cd5f73, 0x0c69a346, 0x34e036c3, 0x5c95bf6b, 0xee4f4379, 0x7f092573, 0x6a57d5e0, 0xd50f659f,
0xd931e110, 0xab0e36a4, 0x1c1878ef, 0x852a0c8b, 0x7a1c0945, 0x932795e1, 0x9769d174, 0x74811abb,
0xab256a5e, 0xffcb49e9, 0x40aa9400, 0x57938786, 0x41d1eb77, 0xde98b089, 0xe8ee38a6, 0x505c73c0,
0x49ed3142, 0xf4083254, 0xa22c2a55, 0xa14c3606, 0x8b060b88, 0x89688eff, 0xf9006b5c, 0x4830826f,
0xb9e5258a, 0x6f57089e, 0xf3cdcc27, 0x737a1d1d, 0x4e3ef76e, 0xea922ff0, 0x6a6776b4, 0xea6989ef,
0xff16a4c3, 0x1587c95e, 0x3b28c5ad, 0x07fe3b4d, 0x3c297bdc, 0x11b84448, 0x5353674d, 0x9dad7729,
0x0cc568f5, 0x352323c2, 0xb29acf5b, 0x73f73e82, 0x82624fee, 0xbcedf56f, 0x27a5f16e, 0xf5e3a22f,
0xebf59351, 0x48e36eb9, 0x48a2ca0e, 0xf8613963, 0xbbb1532f, 0xd36d1b78, 0x8975b60f, 0xc39823ad,
0x1304073b, 0x396aeeac, 0xefb59893, 0x958f8346, 0x9bc8e713, 0x7ce3f522, 0x549c45cc, 0x829a7a8f,
0x78f8933c, 0x0806232f, 0x80ecc61e, 0xc313d91a, 0xc4d8177e, 0x086f84d8, 0x604bd645, 0x0b70533b,
0x482a2cdb, 0xf472fa55, 0xc2a2c923, 0x3a3d288b, 0xd48cd88c, 0xf4b831b2, 0xf460a283, 0xe1800a44,
0x316acade, 0x49950c6a, 0x769ad791, 0xdb0587c2, 0xa4fb0fd8, 0x79f84441, 0xef0687e9, 0x140761e6,
0xcaa68da5, 0xffc4ebd9, 0x4e049033, 0x6522f813, 0x3beac8d7, 0xfc576d57, 0x1d16d6d8, 0x72035c0e,
0x476701e9, 0x687a5a66, 0x92cf6fbf, 0x40b7bc7e, 0x488791ea, 0x3f3c9d5f, 0x473e966e, 0xe12be8d0,
0xc5b220e3, 0x83f5b5d1, 0xf8425ce8, 0x147ffdfe, 0x3c2e9f70, 0xae377b6d, 0xf2ef4032, 0x37e31d6f,
0xe38a8d07, 0x0bab8299, 0x35d0fa8c, 0xb3b7134f, 0x2d261472, 0x729470d9, 0x1f532499, 0xc17c11d9,
0xa75bebb5, 0xe93f4826, 0x66bbaab8, 0x1a1283c2, 0x63630227, 0x30decdde, 0x3a408005, 0x40708778,
0x03c00538, 0x2d4005cf, 0x1540871f, 0x8336b988, 0x0f13206e, 0x4a7a432a, 0xccab4d42, 0x88f8a974,
0xea3c1597, 0x286a36d3, 0x4a379af7, 0x56ed62cc, 0x00a527a7, 0xcdf6e8d2, 0x496e4258, 0xad0963dc,
0x35849058, 0xd5318630, 0x471347de, 0xd5f41679, 0x6c5dfa1c, 0xa2e3962b, 0xa2a9d0cd, 0x51f389b2,
0x2c32d7d9, 0x0bcbb660, 0xfcc65c4d, 0xebae9861, 0xdb306771, 0xddb68d04, 0x349dd702, 0x41601e5c,
0x45e0a6e6, 0x4d47b8b9, 0xb13de5bd, 0x9470a646, 0x4f8d79c8, 0x5198bd57, 0x464f0f41, 0xa3b94eb5,
0x9ba67548, 0xda8ef82a, 0x5e4f5ddf, 0x87362e51, 0xa54fa800, 0x7a170efd, 0x9eaf1ed6, 0xcba3327b,
0x0eb40a70, 0x6c485e61, 0xb5816353, 0x153a356e, 0xe6ce9561, 0x00401a68, 0xed446533, 0x4aeca02f,
0x23a60800, 0x7cd87f07, 0x66449ba2, 0xfd73ef7f, 0x585f6023, 0xca4e9196, 0x7f9703fb, 0x5ca05a49,
0x8fd8e743, 0x2ccc8bf2, 0x0a344fc5, 0xa8820b45, 0x6def5335, 0x6955a016, 0x0caa83f9, 0xe989cb22,
0x404d2481, 0xfca15ea3, 0xa85a37ec, 0xac76359c, 0x418b2607, 0x1825b50c, 0x49eb49f6, 0x474b902a,
0xd449e36e, 0x96fc5196, 0x7539f749, 0xdd08949c, 0xb1bafce2, 0x83cc94fc, 0xa6f5a778, 0xb164ab0f,
0x40f8b398, 0xe241b707, 0xca525e65, 0x06dffc5a, 0xbf7f22ab, 0x3c02be16, 0x904e2b6e, 0x6890df7d,
0xf923628c, 0x730e1349, 0x4813ba35, 0xe4cb5c64, 0x1fcae404, 0x58ee3503, 0x61771f68, 0x1248d918,
0xef90f892, 0x87e0cedc, 0xb19301af, 0x4c0dcf89, 0xed85398c, 0xd05f11ad, 0x8df2b9ca, 0x4430f3c4,
0x3b826d5e, 0x9a8c1301, 0x7a57976f, 0x4e8cecb0, 0xb49a840b, 0x90619865, 0x72d85bcb, 0x8d5800ff,
0x3923dd0e, 0x5325f55d, 0x818f9c43, 0x3defc69e, 0xf80c6347, 0x7bc18ded, 0x702d62ec, 0xeafc05a3,
0x99d0e9af, 0x054be68a, 0x10581c9d, 0x7f191f91, 0xac7a6274, 0x64212eed, 0xcf38d90a, 0xc213eb86,
0x2ccd58b9, 0xbf09bf04, 0x6e7b4f74, 0x6b97d008, 0x2c7ee79c, 0xb782e7ce, 0x4114e61d, 0xfbd160bb,
0x8c0c905e, 0xbd041c0c, 0xcdab6825, 0x5363e19a, 0xd331c54b, 0x9ca28ca4, 0xf98cd90a, 0xe34976be,
0xd4e91fd1, 0xe4e2808b, 0x4d98c9ea, 0xc623d50a, 0x67160a46, 0x4af9b11c, 0x133681f1, 0x37e36ffc,
0x753e969b, 0xd9f11a04, 0x07713bfa, 0x7eb82b2a, 0xc9de023f, 0x222c5422, 0x98a7a7f0, 0x60483a49,
0x8ee12ab3, 0xeb5a1739, 0x834d7849, 0x60c2def7, 0x46a2b355, 0x61ced01e, 0x0b8c93ce, 0x70deadb9,
0xfcc5828f, 0xc5052168, 0x33f1e2b5, 0x40bb1886, 0x282b920f, 0x6f99e8a2, 0x5fae6602, 0xb932618a,
0x17437ece, 0x3d170b7a, 0x858cdb89, 0xd9779b2d, 0xf42c6ce5, 0x7287a3ef, 0xefd61b2b, 0xb7915615,
0xa1fabb8b, 0x67dc4585, 0xd54b6efa, 0xe809553d, 0xacd3fb38, 0x3b4eec6f, 0x13453165, 0x9085b8f1,
0x7cabc3cf, 0xd1913b48, 0xe8d8927c, 0x12bf3231, 0xbf4f37d6, 0x774e5f3a, 0x1229983c, 0x2bf06330,
0xf1daf9fc, 0xf99c1801, 0x33f8ac7f, 0xe9934bb2, 0xb534d378, 0xff559112, 0xcbdec792, 0x96121910,
0xc974af73, 0xf3205eac, 0xd0084acd, 0xaceb2095, 0x83c8ee13, 0x685a9636, 0x8aa9d8c8, 0x3f675f7c,
0xb781f150, 0x12fccd5b, 0x1f677a9a, 0xc3d87358, 0x9c39831b, 0xc2442b23, 0x99cd89fb, 0xbb291f8a,
0xdb08099a, 0xe93ba3cf, 0x23ed731d, 0x56a9efa9, 0x5e64f72b, 0x5c232c3f, 0xfb89bbb4, 0xe1b8f5fb,
0xd08bab44, 0x9e55b788, 0x105ed931, 0x37e86bdf, 0x110eef10, 0xaf751d5e, 0x6338d467, 0x80e8740e,
};
}
/* CxEncryption base branch order
OddBranchOrder
{
case 0: SHR_EAX_CL
case 1: SHL_EAX_CL
case 2: ADD_EAX_EBX
case 3: NEG_EAX; ADD_EAX_EBX
case 4: IMUL_EAX_EBX
case 5: SUB_EAX_EBX
}
EvenBranchOrder
{
case 0: NOT_EAX
case 1: DEC_EAX
case 2: NEG_EAX
case 3: INC_EAX
case 4: MOV_EAX_INDIRECT
case 5: OR_EAX_EBX
case 6: XOR_EAX_IMMED
case 7: ADD_EAX_IMMED
}
*/
}

View File

@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("ArcFormats")]
[assembly: AssemblyDescription("Visual Novel resources library")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany ("mørkt")]
[assembly: AssemblyProduct("ArcFormats")]
[assembly: AssemblyCopyright("Copyright © 2014 mørkt")]
[assembly: AssemblyTrademark("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion ("1.0.2.21")]
[assembly: AssemblyFileVersion ("1.0.2.21")]

View File

@@ -237,5 +237,17 @@ namespace GameRes.Formats.Properties {
this["NPAKey2"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("8")]
public int WARCNameLength {
get {
return ((int)(this["WARCNameLength"]));
}
set {
this["WARCNameLength"] = value;
}
}
}
}

View File

@@ -56,5 +56,8 @@
<Setting Name="NPAKey2" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">555831124</Value>
</Setting>
<Setting Name="WARCNameLength" Type="System.Int32" Scope="User">
<Value Profile="(Default)">8</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -279,6 +279,15 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to File name extension too long..
/// </summary>
public static string MsgExtensionTooLong {
get {
return ResourceManager.GetString("MsgExtensionTooLong", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to File name is too long.
/// </summary>
@@ -315,6 +324,15 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to File name without extension..
/// </summary>
public static string MsgNoExtension {
get {
return ResourceManager.GetString("MsgNoExtension", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Number of files exceedes archive limit..
/// </summary>
@@ -487,6 +505,16 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Maximum file name length
///(not including extension).
/// </summary>
public static string WARCLabelLength {
get {
return ResourceManager.GetString("WARCLabelLength", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Liar-soft game resource archive.
/// </summary>

View File

@@ -192,6 +192,9 @@ predefined encryption scheme.</value>
<data name="MsgEncNotImplemented" xml:space="preserve">
<value>Encryption method not implemented</value>
</data>
<data name="MsgExtensionTooLong" xml:space="preserve">
<value>File name extension too long.</value>
</data>
<data name="MsgFileNameTooLong" xml:space="preserve">
<value>File name is too long</value>
</data>
@@ -204,6 +207,9 @@ predefined encryption scheme.</value>
<data name="MsgInvalidVersion" xml:space="preserve">
<value>Invalid archive version specified.</value>
</data>
<data name="MsgNoExtension" xml:space="preserve">
<value>File name without extension.</value>
</data>
<data name="MsgTooManyFiles" xml:space="preserve">
<value>Number of files exceedes archive limit.</value>
</data>
@@ -262,6 +268,10 @@ predefined encryption scheme.</value>
<data name="TooltipHex" xml:space="preserve">
<value>Hex number</value>
</data>
<data name="WARCLabelLength" xml:space="preserve">
<value>Maximum file name length
(not including extension)</value>
</data>
<data name="XFLDescription" xml:space="preserve">
<value>Liar-soft game resource archive</value>
</data>

View File

@@ -174,6 +174,9 @@
<data name="MsgEncNotImplemented" xml:space="preserve">
<value>Метод шифрования не реализован</value>
</data>
<data name="MsgExtensionTooLong" xml:space="preserve">
<value>Слишком длинное расширение имени файла.</value>
</data>
<data name="MsgFileNameTooLong" xml:space="preserve">
<value>Слишком длинное имя файла</value>
</data>
@@ -186,6 +189,9 @@
<data name="MsgInvalidVersion" xml:space="preserve">
<value>Указана некорректная версия архива.</value>
</data>
<data name="MsgNoExtension" xml:space="preserve">
<value>Имя файла без расширения.</value>
</data>
<data name="MsgTooManyFiles" xml:space="preserve">
<value>Количество файлов превышает ограничения архива.</value>
</data>
@@ -226,6 +232,10 @@
<data name="TooltipHex" xml:space="preserve">
<value>Шестнадцатеричное число</value>
</data>
<data name="WARCLabelLength" xml:space="preserve">
<value>Максимальная длина имени файла
(не считая расширения)</value>
</data>
<data name="XP3CompressContents" xml:space="preserve">
<value>Сжать содержимое</value>
</data>

View File

@@ -58,6 +58,9 @@
<setting name="NPAKey2" serializeAs="String">
<value>555831124</value>
</setting>
<setting name="WARCNameLength" serializeAs="String">
<value>8</value>
</setting>
</GameRes.Formats.Properties.Settings>
</userSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>

View File

@@ -25,8 +25,8 @@
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.1.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
@@ -316,6 +316,9 @@
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>perl "$(SolutionDir)inc-revision.pl" "$(ProjectPath)" $(ConfigurationName)</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -49,6 +49,8 @@ namespace GameRes
/// <summary>Archive contents.</summary>
public ICollection<Entry> Dir { get { return m_dir; } }
public event EventHandler<OverwriteEventArgs> OverwriteNotify;
public ArcFile (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir)
{
m_arc = arc;
@@ -147,7 +149,7 @@ namespace GameRes
/// </summary>
public Stream CreateFile (Entry entry)
{
return m_interface.CreateFile (entry);
return m_interface.CreateFile (entry.Name);
}
#region IDisposable Members
@@ -172,6 +174,12 @@ namespace GameRes
#endregion
}
public class OverwriteEventArgs : EventArgs
{
public string Filename { get; set; }
public bool Overwrite { get; set; }
}
public class AppendStream : System.IO.Stream
{
private Stream m_base;

View File

@@ -392,8 +392,8 @@ namespace GameRes
private uint m_size;
private long m_position;
public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return true; } }
public override bool CanRead { get { return !disposed; } }
public override bool CanSeek { get { return !disposed; } }
public override bool CanWrite { get { return false; } }
public override long Length { get { return m_size; } }
public override long Position
@@ -410,14 +410,27 @@ namespace GameRes
m_position = 0;
}
public ArcStream (ArcView file, long offset, uint size)
public ArcStream (Frame view)
{
m_view = new Frame (file, offset, size);
m_view = view;
m_start = m_view.Offset;
m_size = m_view.Reserved;
m_position = 0;
}
public ArcStream (ArcView file, long offset, uint size)
: this (new Frame (file, offset, size))
{
}
public ArcStream (Frame view, long offset, uint size)
{
m_view = view;
m_start = offset;
m_size = Math.Min (size, m_view.Reserve (offset, size));
m_position = 0;
}
/// <summary>
/// Read stream signature (first 4 bytes) without altering current read position.
/// </summary>

View File

@@ -143,12 +143,7 @@ namespace GameRes
public void Extract (ArcFile file, Entry entry)
{
using (var reader = OpenEntry (file, entry))
{
using (var writer = CreateFile (entry))
{
reader.CopyTo (writer);
}
}
CopyEntry (file, reader, entry);
}
/// <summary>
@@ -159,13 +154,28 @@ namespace GameRes
return arc.File.CreateStream (entry.Offset, entry.Size);
}
public virtual void CopyEntry (ArcFile arc, Stream input, Entry entry)
{
using (var output = CreateFile (entry.Name))
input.CopyTo (output);
}
/// <summary>
/// Create file corresponding to <paramref name="entry"/> in current directory and open it
/// for writing. Overwrites existing file, if any.
/// </summary>
public virtual Stream CreateFile (Entry entry)
public Stream CreateFile (string filename)
{
filename = CreatePath (filename);
if (File.Exists (filename))
{
// query somehow whether to overwrite existing file or not.
}
return File.Create (filename);
}
static public string CreatePath (string filename)
{
string filename = entry.Name;
string dir = Path.GetDirectoryName (filename);
if (!string.IsNullOrEmpty (dir)) // check for malformed filenames
{
@@ -185,7 +195,7 @@ namespace GameRes
filename = Path.Combine (dir, filename);
}
}
return File.Create (filename);
return filename;
}
/// <summary>

View File

@@ -79,6 +79,9 @@
<EmbeddedResource Include="Strings\garStrings.ru-RU.resx" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>perl "$(SolutionDir)inc-revision.pl" "$(ProjectPath)" $(ConfigurationName)</PreBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

View File

@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyTitle("GameRes")]
[assembly: AssemblyDescription("Game Resources class library")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany ("mørkt")]
[assembly: AssemblyProduct("GameRes")]
[assembly: AssemblyCopyright("Copyright © 2014 mørkt")]
[assembly: AssemblyTrademark("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion ("1.0.0.3")]
[assembly: AssemblyFileVersion ("1.0.0.3")]

View File

@@ -162,7 +162,7 @@ namespace GARbro.GUI
void PushRecentFile (string file)
{
var node = m_recent_files.Find (file);
if (node == m_recent_files.First)
if (node != null && node == m_recent_files.First)
return;
if (null == node)
{

View File

@@ -10,7 +10,7 @@ using System.Windows;
[assembly: AssemblyTitle("Game Resource browser")]
[assembly: AssemblyDescription("Game Resource browser")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyCompany ("mørkt")]
[assembly: AssemblyProduct("GARbro.GUI")]
[assembly: AssemblyCopyright("Copyright © 2014 mørkt")]
[assembly: AssemblyTrademark("")]
@@ -51,5 +51,5 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion ("1.0.2.10")]
[assembly: AssemblyFileVersion ("1.0.1.10")]

70
inc-revision.pl Normal file
View File

@@ -0,0 +1,70 @@
#!/usr/bin/perl
#
# increment .Net assembly revision
use strict;
use Win32;
use File::Basename;
use File::Spec;
use File::Temp;
sub get_git_exe {
my $user_app_data = Win32::GetFolderPath (Win32::CSIDL_LOCAL_APPDATA);
my $git_glob = File::Spec->catfile ($user_app_data, 'GitHub', 'PortableGit_*', 'bin', 'git.exe');
my $git_path = glob ($git_glob);
die "PortableGit not found\n" unless -x $git_path;
return $git_path;
}
sub match_version {
return $_[0] =~ /^(\d+)\.(\d+)(?:\.(\d+)\.(\d+))?/;
}
unless (1 == $#ARGV) {
print "usage: inc-revision.pl PROJECT-FILE CONFIG\n";
exit 0;
}
my ($project_path, $config) = @ARGV;
my $project_dir = dirname ($project_path);
my $project_file = basename ($project_path);
my $is_release = 'release' eq lc $config;
chdir $project_dir or die "$project_dir: $!\n";
my $git_exe = get_git_exe;
my $prop_dir = File::Spec->catfile ('.', 'Properties');
my $assembly_info = File::Spec->catfile ($prop_dir, 'AssemblyInfo.cs');
my $revision = `$git_exe rev-list master --count $project_file`;
die "git.exe failed\n" if $? != 0;
chomp $revision;
my $version_changed = 0;
my $tmp_filename;
{
open (my $assembly_file, '<', $assembly_info) or die "${assembly_info}: $!";
my $tmp_output = File::Temp->new (DIR => $prop_dir, UNLINK => 0);
$tmp_filename = $tmp_output->filename;
binmode ($tmp_output, ':crlf');
while (<$assembly_file>) {
m,^//, and next;
/^\[assembly:\s*(Assembly(?:File)?Version)\s*\("(.*?)"\)\]/ and do {
my ($attr, $version) = ($1, $2);
my ($major, $minor, $build, $rev) = match_version ($version);
$build += 1 if $is_release;
my $new_version = "${major}.${minor}.${build}.${revision}";
$_ = "[assembly: ${attr} (\"${new_version}\")]\n";
print "AssemblyVersion: $new_version\n" if $attr eq 'AssemblyVersion';
$version_changed ||= $version ne $new_version;
};
} continue {
print $tmp_output $_;
}
}
if ($version_changed) {
rename $assembly_info, "${assembly_info}~" or die "${assembly_info}: $!";
rename $tmp_filename, $assembly_info or die "${tmp_filename}: $!";
} else {
unlink $tmp_filename;
}