アンパック

復号化したものをアンパックします。

struct Arch {
    magic: u32,
    name_size: u32,
    entry_count: u32,
    entries: Vec<Entry>,
    names: Vec<u8>,        // name_size
}
struct Entry {
    hash: u64,                    // crc64
    offset: u64,
    entry_size: u32,
    number: u32,                // テキストとスクリプトは 0、それ以外は entry_size と同じ
    name_block: u16,
    name_offset: u16,
}
file_name は names の中に Null 終端文字列として格納されている。

file_name 取得例:
file_name_offset = arch.entries[0].name_block * 0x10000 + arch.entries[0].name_offset;
file_name = arch.names[file_name_offset..0x0 まで];

後はこの file_name, entry.offset, entry.entry_size を使ってファイルを出力するだけ。

一点注意すべき部分があって entry.offset は names の次のアドレスからのオフセットになる。
したがって names を読み込んだ時点の位置を base_offset として保持しておくと良い。

アンパックしたファイルの一部は、また暗号化されている。
頭に magic: u32 が付加されているのでそれ以降を Blowfish(カスタム) で復号化すると良い。