Web、サーバ、ソフトウェア、バグ・脆弱性 などの情報を何人かで集まって書いていく IT/Web情報系ブログ

HSPdeco(HSP逆コンパイラ)で復号が失敗する場合がある

投稿日:   最終更新日:2017/01/15  投稿者:xx2zz

HSPdecoというHSPの逆コンパイラに暗号化されたstart.axを復号する機能がついているのですが、ファイルによっては復号に失敗する場合があるので、原因と対策を記しておきます。

hspdeco

原因

総当たりで、復号処理の結果が既知の平文4バイト(“HSP3” or “HSP2”)と一致した値を鍵の候補としているが、偶然平文と一致する値が2つ以上あった場合にエラーとして処理を中断してしまっているため。

対策

平文4バイトと一致した鍵で復号したstart.axの逆コンパイルを行い、正しく逆コンパイルできればそれを鍵候補とする処理を追加する。

というわけで、この処理を追加したコード(パッチ)を置いておきます。
ライセンスはHSPdeco同様パブリックドメインとします。
(追記注:表示されている行数は、追加変更適用後の行数となります。)

KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform decrypter = KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform.CrackEncryption(buffer);

↓↓↓

KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform decrypter = KttK.HspDecompiler.DpmToAx.HspCrypto.HspCryptoTransform.CrackEncryption(buffer, dictionary); // 変更
using System.IO; // 追加
using KttK.HspDecompiler.Ax2ToAs;  // 追加
using KttK.HspDecompiler.Ax3ToAs;  // 追加
internal static HspCryptoTransform CrackEncryption(byte[] encrypted)

↓↓↓

internal static HspCryptoTransform CrackEncryption(byte[] encrypted, Hsp3Dictionary dictionary)
HspCryptoTransform hsp3crypto = CrackEncryption(plain3, encrypted);

↓↓↓

HspCryptoTransform hsp3crypto = CrackEncryption(plain3, encrypted, dictionary);
HspCryptoTransform hsp2crypto = CrackEncryption(plain2, encrypted);

↓↓↓

HspCryptoTransform hsp2crypto = CrackEncryption(plain2, encrypted, dictionary);
internal static HspCryptoTransform CrackEncryption(byte[] plain, byte[] encrypted)

↓↓↓

internal static HspCryptoTransform CrackEncryption(byte[] plain, byte[] encrypted, Hsp3Dictionary dictionary)
if (ok)
	transformList.Add(xoradd);

↓↓↓

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);
    }
}

鍵候補毎に逆コンパイル処理を行うようになるので、ファイルによっては復号に時間がかかります。
本来ならexe内から正しい鍵を抜き取れればいいのですが、面倒なのでこうしています。

- C# ,

Comment

  1. Ronaldo より:

    Much thanks again. Want more.

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事