HSPdecoというHSPの逆コンパイラに暗号化されたstart.axを復号する機能がついているのですが、ファイルによっては復号に失敗する場合があるので、原因と対策を記しておきます。
原因
総当たりで、復号処理の結果が既知の平文4バイト(“HSP3” or “HSP2”)と一致した値を鍵の候補としているが、偶然平文と一致する値が2つ以上あった場合にエラーとして処理を中断してしまっているため。
対策
平文4バイトと一致した鍵で復号したstart.axの逆コンパイルを行い、正しく逆コンパイルできればそれを鍵候補とする処理を追加する。
というわけで、この処理を追加したコード(パッチ)を置いておきます。
ライセンスはHSPdeco同様パブリックドメインとします。
(追記注:表示されている行数は、追加変更適用後の行数となります。)
[code language=”csharp” firstline=”133″ title=”HspDecoder.cs”]
KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform decrypter = KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform.CrackEncryption(buffer);
[/code]↓↓↓[code language=”csharp” firstline=”133″ highlight=”133″ title=”HspDecoder.cs”]
KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform decrypter = KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform.CrackEncryption(buffer, dictionary); // 変更
[/code]
[code language=”csharp” firstline=”4″ highlight=”4″ title=”HspCryptoTransform.cs”]
using System.IO; // 追加
[/code]
[code language=”csharp” firstline=”8″ highlight=”8-9″ title=”HspCryptoTransform.cs”]
using KttK.HspDecompiler.Ax2ToAs; // 追加
using KttK.HspDecompiler.Ax3ToAs; // 追加
[/code]
[code language=”csharp” firstline=”54″ title=”HspCryptoTransform.cs”]
internal static HspCryptoTransform CrackEncryption(byte[] encrypted)
[/code]
↓↓↓
[code language=”csharp” firstline=”54″ highlight=”54″ title=”HspCryptoTransform.cs”]
internal static HspCryptoTransform CrackEncryption(byte[] encrypted, Hsp3Dictionary dictionary)
[/code]
[code language=”csharp” firstline=”61″ title=”HspCryptoTransform.cs”]
HspCryptoTransform hsp3crypto = CrackEncryption(plain3, encrypted);
[/code]
↓↓↓
[code language=”csharp” firstline=”61″ highlight=”61″ title=”HspCryptoTransform.cs”]
HspCryptoTransform hsp3crypto = CrackEncryption(plain3, encrypted, dictionary);
[/code]
[code language=”csharp” firstline=”69″ title=”HspCryptoTransform.cs”]
HspCryptoTransform hsp2crypto = CrackEncryption(plain2, encrypted);
[/code]
↓↓↓
[code language=”csharp” firstline=”69″ highlight=”69″ title=”HspCryptoTransform.cs”]
HspCryptoTransform hsp2crypto = CrackEncryption(plain2, encrypted, dictionary);
[/code]
[code language=”csharp” firstline=”74″ title=”HspCryptoTransform.cs”]
internal static HspCryptoTransform CrackEncryption(byte[] plain, byte[] encrypted)
[/code]
↓↓↓
[code language=”csharp” firstline=”74″ highlight=”74″ title=”HspCryptoTransform.cs”]
internal static HspCryptoTransform CrackEncryption(byte[] plain, byte[] encrypted, Hsp3Dictionary dictionary)
[/code]
[code language=”csharp” firstline=”114″ title=”HspCryptoTransform.cs”]
if (ok)
transformList.Add(xoradd);
[/code]
↓↓↓
[code language=”csharp” firstline=”114″ highlight=”114-146″ title=”HspCryptoTransform.cs”]
if (ok)
{
AbstractAxDecoder decoder = null;
if (plain[3] == 0x32)
{
decoder = new Ax2Decoder();
}
else
{
Ax3Decoder decoder3 = new Ax3Decoder();
decoder3.Dictionary = dictionary;
decoder = decoder3;
}
HspCryptoTransform decryptor = new HspCryptoTransform();
decryptor.xorAdd = xoradd;
byte[] buffer = (byte[])encrypted.Clone();
buffer = decryptor.Decryption(buffer);
MemoryStream stream = new MemoryStream(buffer);
BinaryReader reader = new BinaryReader(stream, Encoding.GetEncoding("SHIFT-JIS"));
try
{
decoder.Decode(reader);
transformList.Add(xoradd);
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
[/code]
鍵候補毎に逆コンパイル処理を行うようになるので、ファイルによっては復号に時間がかかります。
本来ならexe内から正しい鍵を抜き取れればいいのですが、面倒なのでこうしています。
コメント
Much thanks again. Want more.
はじめまして。最近HSPを勉強中のものですが、こちらの公開されているソースコードはどのように使用したらいいでしょうか?こちらのソースコードを入れてHSPdecoをビルドしたらいいのでしょうか。
>こちらのソースコードを入れてHSPdecoをビルドしたらいいのでしょうか。
はい。
このパッチを適用済みのHSPdecoから派生した別のソフトもあるようです。
https://github.com/YSRKEN/HSP-Decompiler