『花咲ワークスプリング!』とかいうえっちなげぇむが来週金曜日発売らしい。
体験版を落としてみると、ゲームデータの中の BGM フォルダに owp というファイルがあるのがわかる。これが BGM のデータっぽいが、いかんせんそこらへんのソフトでは再生できないようだ。
というわけで解読をしよう。
どうせ音声データは OggVorbis だろうという軽い推測のもと、普通の Ogg と並べてバイナリをじっと眺めてみよう。左が owp ファイル、右が ogg だ。右の ogg は oggenc2.87 (libVorbis v1.3.5) を使っている。
左右を見比べると、どうやら 1 バイトが 1 バイトに対応しているっぽいのがわかる。一番最初、ogg では「OggS」の「g (67)」が 2 つならんでいるが、左でもその位置で「^ (5E)」が 2 つならんでいる。さらに、ogg で「NULL (00)」の部分は左では「9 (39)」、「FF」の部分は左で「C6」となっているっぽいこともわかる。
これを対照表にしてみよう。上が owp、下が ogg だ。
39 → 0011 1001 00 → 0000 0000 NULL C6 → 1100 0110 FF → 1111 1111 76 → 0111 0110 4F → 0100 1111 O 5E → 0101 1110 67 → 0110 0111 g 6A → 0110 1010 53 → 0101 0011 S
どうやら、右から 1 桁目、4 桁目、5 桁目、6 桁目が上下でそれぞれ違うっぽい。特に 00 と FF の対照だとよくわかる。とりあえず各バイト、0x39 と XOR を取ってみることにしよう。0x39 と XOR をとれば、1 桁目、4 桁目、5 桁目、6 桁目だけを反転させることができる。
ただ 3MB ぶんもこんなことをやっていたら地球が滅亡してしまうので、プログラムを書こう。今回は C で書いた。
#include <stdio.h>
#include <string.h>
#ifndef BUFSIZE
#define BUFSIZE 65536
#endif
int main(int argc, char const *argv[]) {
int i;
for(i = 0 ; i < argc - 1 ; i++) {
const char* filename = argv[i+1];
FILE *fp = fopen(filename, "rb");
char outfilename[strlen(filename) + 5];
FILE *fpo;
size_t size;
unsigned char buf[BUFSIZE];
printf("Opening... %s\n", filename);
if(fp == NULL) {
printf("Cannot open: %s\n", filename);
continue;
}
sprintf(outfilename, "%s.ogg", filename);
printf("Opening... %s\n", outfilename);
if ((fpo = fopen(outfilename, "wb")) == NULL) {
printf("Cannot open: %s\n", outfilename);
fclose(fp);
continue;
}
while ((size = fread(buf, sizeof(unsigned char), BUFSIZE, fp))) {
int j;
for (j = 0 ; j < size ; j++)
buf[j] = buf[j] ^ 0x39;
fwrite(buf, sizeof(unsigned char), size, fpo);
}
fclose(fp);
fclose(fpo);
printf("Complete: %s\n\n", filename);
}
return 0;
}
後はコマンドライン引数に owp ファイルを指定してやれば、ogg ファイルがぽいぽい生成される。
試しに再生してみると、なんとまあ軽快な音楽が流れてきた。
bgm81.owp は主題歌の Girl meets Love のインストになっているようである。
早くえっちげの BGM をラクに聞きたい方は、どうぞコンパイルして使ってください、ということで。
ちなみにカルマルカ*サークル製品版の BGM データもこれによって復号できる。あと XOR の性質的に、このコードに ogg を渡してやれば owp が作れる。