アンパック
復号化したものをアンパックします。
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(カスタム) で復号化すると良い。
復号化したものをアンパックします。
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(カスタム) で復号化すると良い。
コメント