他人の空似

2009 年 4 月 7 日

某東方二次製作ゲームの解析過程

Filed under: 解析 — 中の人 @ 10:39 AM

開発滞りまくってそろそろ罵声飛んできそうな状態ですが
火打石的依頼が舞い込んできたので、その過程を解説風に書いてみるテスト。

概要:とあるソフトの解析依頼
目的:ソフト内で使用されているデータの切り出し(可能であれば一般形式への変換も)
制限:ソフトの立ち上げ禁止

三つ目はWeb認証があるとかで、変なことされてネット対戦出来なくなると困るからだとか
起動もしないで解析とか無茶言うなって話ですが、考えてみれば地霊殿の解析はバイナリエディターだけだったなということで試しにやってみることに。


解析1:BGMファイルの取得

BGMというのはファイル容量が大きいためメモリー上に保持し辛く、遅延がダイレクトに影響を及ぼすため
大抵はその他ファイルとは別に展開が高速なフォーマットでアーカイブされていることが多いです。

今回のソフトもその例に漏れず、.musという判りやすい拡張子でどでかいファイルを保持していました。
本来ならこのファイルを撤去した上で起動し音がならないか試すのですが、今回は起動禁止なので音楽ファイルと決め打つことにします。

とりあえず先頭を少量切り出してきてバイナリエディタで開きます(容量が大きいため、そのままだと固まる)
するとこんな感じ(一部実際の内容から変えてあります)
kaiseki1
oggという音楽ファイルの拡張子が見えるので間違ってはいない様子。

おそらくは最初のPACKが識別子、その後80byte区切りでファイル情報らしきものが仕舞われているのが見て取れます。
問題はPACKから最初のファイル名までの4byteが一つ目の音楽ファイルに関する情報なのか、このファイル全体に関係する情報なのか判別付かない点ですが
二個目以降のファイル名の前4byteを見てみると数字の傾向が違うことが見て取れるので、今はとりあえずファイル全体に関連する情報だと思っておくことにします。

次にこの80byteが具体的にどういう構造をしているのか調べる作業に入ります。
まず膨大な0の山と、ファイル名~0で埋まっている部分を合計するとどれも64byteであることから
このフォーマットにおいてファイル名は64byteの決めうちであることが判ります。
残り16byteも断定したいところですが、今はまだどこで区切ればいいのかも判然としないので後回しにします。

ここで少し話がそれますが、一般にこういったアーカイブ形式の場合
ファイルリストと一緒にファイルの個数、もしくはファイルリストのサイズがついてくるか
ファイルリストがリスト構造になっており、終端まで辿ることで個数を判別できる仕様になっていることがほとんどです。

ですが、今はまだそれらしき情報を見つけていません、そこでこのファイルにいくつファイルが格納されているのか調べることにします。
その結果41個入っているらしいことが判りました。16進数になおすと0x29となります。
そう、先ほど後回しにしたPACKの後の4byteも同じく0x29でビンゴです。これがファイル個数だと思っていいでしょう。

念のためリスト構造の可能性を考えて内容不明の16byteから次のファイル名情報を指していそうな絶対or相対アドレスを探しますが見つかりません。
これはデータそのものに関するデータで、ファイルリスト自体に関連する情報ではないようです。

本来はここで16byteを全て切り出し1/2/4byteごとに区切ってみて特異点がないか探す作業になるのですが、流石に面倒くさいので別方向からアプローチすることにします。
kaiseki2

これは適当に手元にあったwavをoggエンコードした物をバイナリエディタで開いた画像です。
先頭4byteのOggSはoggフォーマットであることを示す識別子で、oggフォーマットのファイルであれば全て先頭4byteはこうなっています。
今回は既にファイル名からoggファイルが格納されていることはわかっているので、ためしにOggSで検索かけてみることにします、すると……
kaiseki3

見事にヒットしました、その後の流れを見比べてもoggの生データであると見て間違いなさそうです。
さらにこのoggファイルのアドレスをよく見ると面白いことがわかります。
一枚目の画像をよく見てください、二個目のファイル名の前8byteの所に0x00000D00と格納されているのが見て取れます。
試しにそのほかのファイル名の前8byteが指すアドレスの部分を見てみても全てOggSの識別子に行き当たります。
つまりこれがファイル格納位置だということですね。

残るはファイルサイズですが、ファイル位置がわかっているため次のファイル位置を元におおよそのサイズを割り出すことが出来ます。
今回の例で言えば二つ目のファイル位置が0x0005E700であるため、0x5E700-0xD00で0x5DA00以下であることがわかります。
ちょうど一つ目のファイル位置の次4byteに非常に近い数値が格納されているのがわかりますね。
念のため他のファイル情報も計算して見比べてみましたが全て非常に近い数値を取っていることがわかります。
つまり、これがファイルサイズということになります。

試しにバイナリエディタを使って手動で切り出してみましたが問題なく再生されました。
どうやらこれで問題ないようです、やったね!

ここまでをまとめると
4byte:PACK
4byte:格納されたファイル個数
ここからファイルリスト
64byte:ファイル名
8byte:不明
4byteファイル格納位置
4byte:ファイルサイズ
となります。

不明の8byteが気になりますが、自分にはわからなかったため気にしないことにします。
そんな適当でいいのかと思う人もいるかもしれませんが、解析の世界では割と普通。
判らないならとりあえず無視して、あとで食い違うことがあったらそのときに引っ張り出して繰ればいいのです。

ちなみに、上記の結果を基にした切り出しツールはCUIで余分な機能を色々つけても100行の1800文字で収まります。
下手をすればC言語始めて一週間の人でも書けちゃうレベル。

解析1と銘打ってあるとおりこのあと画像やら効果音も切り出していますが、そっちはまだ現在進行形なので終わった頃にでも

Powered by WordPress