mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 13:45:34 +08:00
implemented '*_scr.med' archives decryption.
This commit is contained in:
parent
acb32ac1fe
commit
b18ede8684
@ -87,6 +87,9 @@
|
||||
<Compile Include="Cri\ImageSPC.cs" />
|
||||
<Compile Include="Cri\ImageXTX.cs" />
|
||||
<Compile Include="DxLib\ArcMED.cs" />
|
||||
<Compile Include="DxLib\WidgetSCR.xaml.cs">
|
||||
<DependentUpon>WidgetSCR.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="elf\ArcVOL.cs" />
|
||||
<Compile Include="EmonEngine\ArcEME.cs" />
|
||||
<Compile Include="EmonEngine\ImageBMP.cs" />
|
||||
@ -532,6 +535,10 @@
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="DxLib\WidgetSCR.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="FC01\WidgetMCG.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -27,9 +27,69 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Formats.Properties;
|
||||
using GameRes.Formats.Strings;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.DxLib
|
||||
{
|
||||
public interface IScriptEncryption
|
||||
{
|
||||
int StartOffset { get; }
|
||||
|
||||
bool IsEncrypted (byte[] data);
|
||||
void Decrypt (byte[] data, int offset, int length);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class FudegakiEncryption : IScriptEncryption
|
||||
{
|
||||
readonly byte[] Key;
|
||||
|
||||
public FudegakiEncryption (string keyword)
|
||||
{
|
||||
Key = Encodings.cp932.GetBytes (keyword);
|
||||
}
|
||||
|
||||
public int StartOffset { get { return 0x10; } }
|
||||
|
||||
public bool IsEncrypted (byte[] data)
|
||||
{
|
||||
return LittleEndian.ToInt32 (data, 0) + 0x10 == data.Length && Key.Length > 0;
|
||||
}
|
||||
|
||||
public void Decrypt (byte[] data, int offset, int length)
|
||||
{
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
data[offset+i] += Key[(offset+i) % Key.Length];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MedOptions : ResourceOptions
|
||||
{
|
||||
public IScriptEncryption Encryption;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ScrMedScheme : ResourceScheme
|
||||
{
|
||||
public Dictionary<string, IScriptEncryption> KnownSchemes;
|
||||
}
|
||||
|
||||
internal class ScrMedArchive : ArcFile
|
||||
{
|
||||
public readonly IScriptEncryption Encryption;
|
||||
|
||||
public ScrMedArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, IScriptEncryption enc)
|
||||
: base (arc, impl, dir)
|
||||
{
|
||||
Encryption = enc;
|
||||
}
|
||||
}
|
||||
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class MedOpener : ArchiveFormat
|
||||
{
|
||||
@ -41,6 +101,14 @@ namespace GameRes.Formats.DxLib
|
||||
|
||||
static readonly Lazy<ImageFormat> PrsFormat = new Lazy<ImageFormat> (() => ImageFormat.FindByTag ("PRS"));
|
||||
|
||||
public static Dictionary<string, IScriptEncryption> KnownSchemes = new Dictionary<string, IScriptEncryption>();
|
||||
|
||||
public override ResourceScheme Scheme
|
||||
{
|
||||
get { return new ScrMedScheme { KnownSchemes = KnownSchemes }; }
|
||||
set { KnownSchemes = ((ScrMedScheme)value).KnownSchemes; }
|
||||
}
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
if (!file.View.AsciiEqual (0, "MD"))
|
||||
@ -72,7 +140,49 @@ namespace GameRes.Formats.DxLib
|
||||
dir.Add (entry);
|
||||
index_offset += 8;
|
||||
}
|
||||
var base_name = Path.GetFileNameWithoutExtension (file.Name);
|
||||
if (base_name.EndsWith ("_scr", StringComparison.InvariantCultureIgnoreCase)
|
||||
&& KnownSchemes.Count > 0)
|
||||
{
|
||||
var options = Query<MedOptions> (arcStrings.ArcEncryptedNotice);
|
||||
if (options.Encryption != null)
|
||||
return new ScrMedArchive (file, this, dir, options.Encryption);
|
||||
}
|
||||
return new ArcFile (file, this, dir);
|
||||
}
|
||||
|
||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||
{
|
||||
var scr_arc = arc as ScrMedArchive;
|
||||
if (null == scr_arc || entry.Size <= scr_arc.Encryption.StartOffset)
|
||||
return base.OpenEntry (arc, entry);
|
||||
var data = arc.File.View.ReadBytes (entry.Offset, entry.Size);
|
||||
if (scr_arc.Encryption.IsEncrypted (data))
|
||||
{
|
||||
var offset = scr_arc.Encryption.StartOffset;
|
||||
scr_arc.Encryption.Decrypt (data, offset, data.Length-offset);
|
||||
}
|
||||
return new MemoryStream (data);
|
||||
}
|
||||
|
||||
public override ResourceOptions GetDefaultOptions ()
|
||||
{
|
||||
return new MedOptions {
|
||||
Encryption = GetEncryption (Settings.Default.MEDScriptScheme),
|
||||
};
|
||||
}
|
||||
|
||||
public override object GetAccessWidget ()
|
||||
{
|
||||
return new GUI.WidgetSCR();
|
||||
}
|
||||
|
||||
public static IScriptEncryption GetEncryption (string scheme)
|
||||
{
|
||||
IScriptEncryption enc;
|
||||
if (string.IsNullOrEmpty (scheme) || !KnownSchemes.TryGetValue (scheme, out enc))
|
||||
return null;
|
||||
return enc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
ArcFormats/DxLib/WidgetSCR.xaml
Normal file
9
ArcFormats/DxLib/WidgetSCR.xaml
Normal file
@ -0,0 +1,9 @@
|
||||
<StackPanel x:Class="GameRes.Formats.GUI.WidgetSCR"
|
||||
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"
|
||||
xmlns:d="clr-namespace:GameRes.Formats.DxLib">
|
||||
<ComboBox Name="ScriptScheme" ItemsSource="{Binding}" Width="250"
|
||||
SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=MEDScriptScheme, Mode=TwoWay}"/>
|
||||
</StackPanel>
|
22
ArcFormats/DxLib/WidgetSCR.xaml.cs
Normal file
22
ArcFormats/DxLib/WidgetSCR.xaml.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System.Windows.Controls;
|
||||
using System.Linq;
|
||||
using GameRes.Formats.DxLib;
|
||||
using GameRes.Formats.Strings;
|
||||
|
||||
namespace GameRes.Formats.GUI
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for WidgetSCR.xaml
|
||||
/// </summary>
|
||||
public partial class WidgetSCR : StackPanel
|
||||
{
|
||||
public WidgetSCR()
|
||||
{
|
||||
InitializeComponent();
|
||||
var keys = new string[] { arcStrings.ArcIgnoreEncryption };
|
||||
ScriptScheme.ItemsSource = keys.Concat (MedOpener.KnownSchemes.Keys.OrderBy (x => x));
|
||||
if (-1 == ScriptScheme.SelectedIndex)
|
||||
ScriptScheme.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
12
ArcFormats/Properties/Settings.Designer.cs
generated
12
ArcFormats/Properties/Settings.Designer.cs
generated
@ -537,5 +537,17 @@ namespace GameRes.Formats.Properties {
|
||||
this["NCARCScheme"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string MEDScriptScheme {
|
||||
get {
|
||||
return ((string)(this["MEDScriptScheme"]));
|
||||
}
|
||||
set {
|
||||
this["MEDScriptScheme"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,5 +131,8 @@
|
||||
<Setting Name="NCARCScheme" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="MEDScriptScheme" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
@ -133,6 +133,9 @@
|
||||
<setting name="NCARCScheme" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="MEDScriptScheme" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
</GameRes.Formats.Properties.Settings>
|
||||
</userSettings>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
|
||||
|
Loading…
Reference in New Issue
Block a user