ファイルフォーマットの解析

戻る

ファイルフォーマットの解析について

ファイルフォーマットの解析には、バイナリエディタでファイルの中身を解析する方法、
デバッガでファイルの展開方法をトレースする方法があります。

デバッガを使う方法は、当たりを付けて解析しないと無駄に時間だけが過ぎていきます。
最初は、あまり手を出さないほうがいいと思います。
簡単なものなら、バイナリエディタで十分に解析可能です。
ここでは、とりあえずバイナリエディタでファイルを直接見ていきます。

ぱすちゃでは、セーブデータの顔画像にQNTが使われているので、これを見てみましょう。
なお、ALDファイルの中にも大量のQNTファイルが含まれています。
ALDファイルを展開するために、どこかでALD用のプラグインを拾ってきてください。

途中、わからない単語があれば、検索して下さい。
とりあえず、解析部分は飛ばして見てもらってもいいと思います。

ヘッダの解析

       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
00000  51 4E 54 00 02 00 00 00 44 00 00 00 00 00 00 00 QNT    D       
00010  00 00 00 00 20 03 00 00 58 02 00 00 18 00 00 00        X     
00020  01 00 00 00 50 75 03 00 A7 44 00 00 1E AA 33 0D    Pu ァD  ェ3 
00030  90 AA C4 01 3A 75 49 EB 91 AA C4 01 00 00 00 00 征ト:uI・ェト    
00040  00 00 00 00 78 DA EC BD 77 8C 65 D9 9D 1E 76 CE     xレ・w憩ル・vホ

QNTファイルの、先頭の64バイトをバイナリエディタで表示したものです。

先頭の3バイトにQNTとあり、ファイル識別子のようです。
これは分かりやすいです。
また、00010の行に、20 03 00 00、58 02 00 00というデータがあります。
4バイト(32bit)のリトルエンディアン で見ると、10進数でそれぞれ800, 600となります。

これは、画像データでお馴染みの値で、画像の幅、高さです。
同様に、18 00 00 00は24bitのフルカラーということでしょう。
この辺は、もはや慣れです。
一つのデータだけ見ていても分からないことがあるので、 大きなファイルや小さなファイル、いろいろ見比べてみてください。

なお、Windowではほとんどの場合リトルエンディアンです。
以下、0x00000320は16進数で、リトルエンディアンで20 03 00 00のことです。

次に、00020の行を見ると、50 75 03 00、 A7 44 00 00となっています。
上位が00 00ですので、なんらかの意味のある32bitデータのようです。
ファイルサイズと比べてみると、0x00037550とほぼ同じであることが分かります。
さらに、0x00037550と0x000044A7を足すとファイルサイズとの差がわずか0x44です。
ここで、00000の行を見ると、44 00 00 00というのがあります。

どうも、0x44というのは、ファイル情報を格納したヘッダのサイズのようです。
これらから推定すると、このQNTファイルの内容は以下のようになっています。

ヘッダサイズ ・・・ 0x44
画像データのサイズ ・・・ 0x00037550
付加データ(?) ・・・ 0x000044A7

・追記
00000の行にある02 00 00 00は、QNTフォーマットのバージョンです。
ぱすちゃはバージョン2のようです。
少し前のアリスソフトのゲームでは、0や1でした。
バージョン0では、ヘッダのフォーマットが少し異なっていたようです。

画像データの展開

他の不明なデータは置いておいて、画像データの先頭である、
0x0044を見てみると、78 DAという2バイトのデータがあります。

これを見て、ピンと来る人は・・・・いないでしょうね。
バイナリエディタでデータを見慣れている人なら、
ひょっとしたら気づくかもしれません。
実はこれ、 ZLIB ヘッダの典型的なパターンです。
78 DAと78 9Cがよく使われます。

ZLIBは、拡張LZ77とハフマン符号の2段圧縮になっているので、
デバッガでまともに追いかけると大変です。
ヘッダだけ見ると単純そうだからQNTをサンプルに選んだんだけど、
失敗だったかも。

付加データの先頭、0x44 + 0x00037550を見ると、ここも78 DAとなっています。
同様にZLIBで圧縮されているようです。
ZLIBデータの展開については、適当に検索してください。

画像データの解析

画像データをZLIBで展開し、BMPのヘッダくっつけて、とりあえず体裁を整えてみます。
これできれいに表示されれば楽でいいんですが、そうはいきません
同じような画像が9個、3x3に分割されて表示されます。

この3×3というのがミソです。
24bitのBMPファイルというのは、
BGR, BGR, BGR, ... と1ピクセルずつ、青、緑、赤のデータが並んでいます。

3×3になるということは、3行分のデータが1行目に来てしまっているということです。
よって、データがBBB..., GGG..., RRR...と、色ごとにデータ並んでいることが考えられます。
同じようなデータが並んでいた方が圧縮率がよくなるため、
色ごとにデータを分けて格納している画像フォーマットはけっこうあります。

色ごとに並んだデータを、BGRのピクセルごとのデータに並びかえてみると、
今度は背景が真っ黒で、右に半分ずれたような画像が表示されます。
この辺になってくると、さずがにデバッガで追いかけた方が楽かも。

いろいろ試行錯誤してみると、2×2ピクセルが1データとして並んでいることがわかりました。
2×2のデータは、以下の順番で格納されています。

これで、ようやく一枚の画像が表示されます。
でもまだ、真っ黒な背景に輪郭だけが表示された妙な画像です。
これはよくあるパターンで、ピクセルデータがそのまま入っているのではなく、
一つ前のピクセルとの差分データが入っているからです。

背景部分は同じようなデータが連続するため00、つまり黒になります。
そして、輪郭部分はデータが急激に変化するため、色が付いて表示されるわけです。
QNTファイルの場合、左のピクセルと上のピクセルの平均との差分をとっています。

2×2ピクセルをひとまとまりとし、さらに差分をとることで、
同じようなデータが連続しやすくなり、圧縮率を高めているわけですね。

このように並び替えると、ようやくフルカラーの綺麗な画像になります。
あとは、画像データの後ろに格納されている、付加データです。
ZLIBで展開された付加データのサイズをみると0x0007530で、
画像サイズ0x0015F900のちょうど3分の1になっています。
結論から言うと、これは αチャンネル です。

この辺は、勘です。 ピクセルデータとαデータが分離して格納されているは珍しいですが、
αチャンネルは通常8bitですので、
サイズだけ見れば予想がついてしまいます。

QNTではヘッダサイズも画像サイズも明示的に書いてありますが、
書いてないフォーマットも多いです。
画像の高さと幅がわかれば画像のサイズが計算できますので、
バイナリエディタでデータのサイズや並びを見ていると、解析の手掛りになります。


戻る inserted by FC2 system