2015年10月
SCL 解析 (1)
MCSM 解析 (3)
アンパック
復号化したものをアンパックします。
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(カスタム) で復号化すると良い。
MCSM 解析 (2)
アンパック(復号化):
このファイルは deflate 圧縮さらに Blowfish(カスタム) で暗号化されていますので、アンパックする前に復号化する必要があります。
Key:
Blowfish なので key が必要。 key の場所。
key_length = 0x37,
key_offset = project_lang.prop の前 0x38 or
{
cc
68 ? ? ? ?
E8 ? ? ? ?
C3
cc
}
ファイル構造:
struct Arch {
version: u32,
chunk_size: u32,
chunk_count: u32,
chunk_offsets: Vec<u64>,
file_size: u64,
chunks: <u8>,
}
基本フロー:
chunk_offset から size (chunk_offset[i+1] - chunk_offset[i]) 分 Chunk を取得。
取得データを Blowfish(カスタム) で上記の key を使って復号化。
size が chunk_size より小さければ圧縮されているので defrate で解凍する。
以上を chunk_count 分繰り返す。
Blowfish(カスタム):
暗号化は Blowfish なんですが若干カスタマイズされています。
P,S 初期化時 S[0][118] はバイトスワップ
P の配列順番が
P{[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17]}
↓
P{[0],[3],[4],[1],[2],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17]}
ですが、expand_key の時(初期化時)は元の順番の P を使用する。
カスタマイズはこの2点
Block は LittleEndian
以上で復号可
このファイルは deflate 圧縮さらに Blowfish(カスタム) で暗号化されていますので、アンパックする前に復号化する必要があります。
Key:
Blowfish なので key が必要。 key の場所。
key_length = 0x37,
key_offset = project_lang.prop の前 0x38 or
{
cc
68 ? ? ? ?
E8 ? ? ? ?
C3
cc
}
ファイル構造:
struct Arch {
version: u32,
chunk_size: u32,
chunk_count: u32,
chunk_offsets: Vec<u64>,
file_size: u64,
chunks: <u8>,
}
基本フロー:
chunk_offset から size (chunk_offset[i+1] - chunk_offset[i]) 分 Chunk を取得。
取得データを Blowfish(カスタム) で上記の key を使って復号化。
size が chunk_size より小さければ圧縮されているので defrate で解凍する。
以上を chunk_count 分繰り返す。
Blowfish(カスタム):
暗号化は Blowfish なんですが若干カスタマイズされています。
P,S 初期化時 S[0][118] はバイトスワップ
P の配列順番が
P{[0],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17]}
↓
P{[0],[3],[4],[1],[2],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17]}
ですが、expand_key の時(初期化時)は元の順番の P を使用する。
カスタマイズはこの2点
Block は LittleEndian
以上で復号可
MCSM 解析 (1)
諸事情により、現時点では何のローカライズなのかは伏せておきます。ごめんなさい。
概要:
画像
概要:
- Unpack (Decrypt)
- Unpack
- ローカライズデータ
- Font (難しそうなのでやらないかも)
画像