首先,不要问我这是什么游戏,还有这个游戏为什么是H的问题。我只想说,我是冲着曾经某人在ACFUN上投稿一个名为“物种已经无法阻止霓红人民”的视频来折腾这玩艺的。
其次,我不想写工具,也许那天我会自己写一个自己用。毕竟自己用的写的简陋一些,连什么说明也不写不会有关系。更重要的是我不想被要求再写封装工具。
最后,我想说的是,这个游戏的解包相比而言是相当的简单。我没有技术去解包其他一些奇怪的东西。
如果你只是想研究解包的话,我推荐你去下300M的体验版就OK了,地址会在最后隐藏的。如果你还有其他什么奇怪的需求,请去下载1.57G的完整版,地址同样在最后隐藏。

好了,正文吧。

我们先看目录构成:
E:\PrincessX 的目录

2011/09/25  18:47    <DIR>          cdvaw    这里面全是OGG
2011/09/25  18:48    <DIR>          dwq      没仔细看,不过我觉得里面全是PNG
2011/09/25  19:16    <DIR>          init2    这里面全是各种各样的配置文件
2011/09/25  18:48    <DIR>          movie    这里面只有一个文件,那个是OP动画……
2011/02/12  10:19           512,640 nnnConfig2.exe  配置程序,没我什么事情。
2011/09/25  18:48    <DIR>          nya      同样的一些配置文件。
2011/09/25  18:48    <DIR>          oggvorbis    这里面只有一个oggvorbis的版权txt……
2011/05/26  04:04         2,149,376 PrincessX.exe  主程序,同样的。
2011/09/25  18:51             4,236 readme.txt
2011/09/25  18:48    <DIR>          sav      存档文件
2011/09/25  18:48    <DIR>          spt      脚本,想阅读日文H小说的可以关注这个文件夹的解包。
2011/09/25  18:48            29,601 unins000.dat
2011/09/25  18:46         1,121,644 unins000.exe
2011/09/25  18:48    <DIR>          vaw      这个是游戏里面的CV的各种正常或奇怪的语音。
2011/09/25  18:48    <DIR>          wgq      这个是音乐文件夹。
               6 个文件      3,817,497 字节
              12 个目录 168,646,770,688 可用字节

工具:OD,WinHex,FileEncrypter。

解包顺序不是按上面的顺序,是按难易程序顺序写的。

1、WGQ文件夹
里面全是.wgq文件,随便拖一个丢入WinHex:
00000000   20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  4F 47 47 20 20 20 20 20  20 20 20 20 20 20 20 20                   OGG             
00000020   20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  50 41 43 4B 54 59 50 45  3D 36 20 20 20 20 20 20                   PACKTYPE=6      
00000040   4F 67 67 53 00 02 00 00  00 00 00 00 00 00 0A 60  00 00 00 00 00 00 74 FE  E2 93 01 1E 01 76 6F 72   OggS...........`......t?..vor
00000060   62 69 73 00 00 00 00 02  44 AC 00 00 00 00 00 00  03 EE 02 00 00 00 00 00  B8 01 4F 67 67 53 00 00   bis.....D?......?.....?OggS..
00000080   00 00 00 00 00 00 00 00  0A 60 00 00 01 00 00 00  12 0B 03 10 10 2D FF FF  FF FF FF FF FF FF FF FF   .........`...........-
000000A0   FF FF FF FF 71 03 76 6F  72 62 69 73 1D 00 00 00  58 69 70 68 2E 4F 72 67  20 6C 69 62 56 6F 72 62   q.vorbis....Xiph.Org libVorb

这里都猜到了这就是ogg音乐文件,直接改后缀名就OK。
值得一提的是px01op_m.wgq和px02op_m.wgq都是OP歌曲,但是看文件大小相差接近一倍就可以想到,前面那个是short ver,后面的是完整版。

2、 init2文件夹和nya文件夹
这2个文件夹放在一起是因为他们里面只有2种文件fxf和xtx。
这2种文件实质上都是txt文件,但是不同是xtx是未加密,直接打开可读(非日文OS请注意加载Apploc,而且x64版本的notepad是不受Apploc影响的)。
fxf也是txt,但是其中的内容是与0xff按字节Xor的。这时候用FileEncrypter同样的异或就OK了,但是遗憾的是FileEncrypter需要起始位置至少是1,这使得第0个字节没有被处理,这里一般可以自己动手算一下,然后用WinHex和谐一下,或者自己写工具。

3、dwq文件夹
这里面有2种文件,一种是大体积的gpk,另一种是小体积的gtb。思考一下不难想出,一个是文件数据集合,另一个是描述表。
我们把sc0.gtb扔进WinHex看下          (选这文件是因为他的体积小,至少不会让这篇文章被二进制淹没)

00000000   3B 00 00 00 
                       00 00 00 00  09 00 00 00 12 00 00 00  1B 00 00 00 24 00 00 00  2D 00 00 00 36 00 00 00   
00000020   3F 00 00 00 48 00 00 00  51 00 00 00 5A 00 00 00  63 00 00 00 6C 00 00 00  75 00 00 00 7E 00 00 00   
00000040   87 00 00 00 90 00 00 00  99 00 00 00 A2 00 00 00  AB 00 00 00 B4 00 00 00  BD 00 00 00 C6 00 00 00   
00000060   CF 00 00 00 D8 00 00 00  E1 00 00 00 EA 00 00 00  F3 00 00 00 FC 00 00 00  05 01 00 00 0E 01 00 00   
00000080   17 01 00 00 20 01 00 00  29 01 00 00 32 01 00 00  3B 01 00 00 44 01 00 00  4D 01 00 00 56 01 00 00   
000000A0   5F 01 00 00 68 01 00 00  71 01 00 00 7A 01 00 00  83 01 00 00 8C 01 00 00  95 01 00 00 9E 01 00 00   
000000C0   A7 01 00 00 B0 01 00 00  B9 01 00 00 C2 01 00 00  CB 01 00 00 D4 01 00 00  DD 01 00 00 E6 01 00 00   
000000E0   EF 01 00 00 F8 01 00 00  01 02 00 00 0A 02 00 00  
                                                             00 00 00 00 63 E6 00 00  8B B7 01 00 E0 7F 02 00   
00000100   9D 54 03 00 8C 21 04 00  6A E8 04 00 7B C3 05 00  12 B5 06 00 86 9F 07 00  FF 89 08 00 E3 76 09 00   
00000120   23 43 0A 00 E7 0F 0B 00  C8 DB 0B 00 B9 B5 0C 00  B0 98 0D 00 FD 7F 0E 00  98 47 0F 00 FC 14 10 00   
00000140   FE F3 10 00 62 DC 11 00  5A BA 12 00 2A 92 13 00  43 5F 14 00 2F 2C 15 00  F7 E3 15 00 2B AD 16 00   
00000160   A1 44 17 00 B1 F6 17 00  25 C6 18 00 AF 81 19 00  8D 70 1A 00 F4 1F 1B 00  2C DE 1B 00 B5 B7 1C 00   
00000180   8D 74 1D 00 BA 3E 1E 00  F1 EC 1E 00 74 AD 1F 00  39 4F 20 00 46 08 21 00  6D A6 21 00 BF 5E 22 00   
000001A0   C0 FE 22 00 82 9B 23 00  84 5D 24 00 7F 07 25 00  BB ED 25 00 79 BB 26 00  3D A2 27 00 01 70 28 00   
000001C0   AF 35 29 00 0D F7 29 00  5B 8A 2A 00 08 3B 2B 00  F9 36 2C 00 64 12 2D 00  BE D2 2D 00
                                                                                                  73 63 5F 70                              sc_p
000001E0   72 78 30 31 00 73 63 5F  70 72 78 30 32 00 73 63  5F 70 72 78 30 33 00 73  63 5F 70 72 78 30 34 00   rx01.sc_prx02.sc_prx03.sc_prx04.
00000200   73 63 5F 70 72 78 30 35  00 73 63 5F 70 72 78 30  36 00 73 63 5F 70 72 78  30 37 00 73 63 5F 70 72   sc_prx05.sc_prx06.sc_prx07.sc_pr
00000220   78 30 38 00 73 63 5F 70  72 78 30 39 00 73 63 5F  70 72 78 31 30 00 73 63  5F 70 72 78 31 31 00 73   x08.sc_prx09.sc_prx10.sc_prx11.s
00000240   63 5F 70 72 78 31 32 00  73 63 5F 70 72 78 31 33  00 73 63 5F 70 72 78 31  34 00 73 63 5F 70 72 78   c_prx12.sc_prx13.sc_prx14.sc_prx
00000260   31 35 00 73 63 5F 70 72  78 31 36 00 73 63 5F 70  72 78 31 37 00 73 63 5F  70 72 78 31 38 00 73 63   15.sc_prx16.sc_prx17.sc_prx18.sc
00000280   5F 70 72 78 31 39 00 73  63 5F 70 72 78 32 30 00  73 63 5F 70 72 78 32 31  00 73 63 5F 70 72 78 32   _prx19.sc_prx20.sc_prx21.sc_prx2
000002A0   32 00 73 63 5F 70 72 78  32 33 00 73 63 5F 70 72  78 32 34 00 73 63 5F 70  72 78 32 35 00 73 63 5F   2.sc_prx23.sc_prx24.sc_prx25.sc_
000002C0   70 72 78 32 36 00 73 63  5F 70 72 78 32 37 00 73  63 5F 70 72 78 32 38 00  73 63 5F 70 72 78 32 39   prx26.sc_prx27.sc_prx28.sc_prx29
000002E0   00 73 63 5F 70 72 78 33  30 00 73 63 5F 70 72 78  33 31 00 73 63 5F 70 72  78 33 32 00 73 63 5F 70   .sc_prx30.sc_prx31.sc_prx32.sc_p
00000300   72 78 33 33 00 73 63 5F  70 72 78 33 34 00 73 63  5F 70 72 78 33 35 00 73  63 5F 70 72 78 33 36 00   rx33.sc_prx34.sc_prx35.sc_prx36.
00000320   73 63 5F 70 72 78 33 37  00 73 63 5F 70 72 78 33  38 00 73 63 5F 70 72 78  33 39 00 73 63 5F 70 72   sc_prx37.sc_prx38.sc_prx39.sc_pr
00000340   78 34 30 00 73 63 5F 70  72 78 34 31 00 73 63 5F  70 72 78 34 32 00 73 63  5F 70 72 78 34 33 00 73   x40.sc_prx41.sc_prx42.sc_prx43.s
00000360   63 5F 70 72 78 34 34 00  73 63 5F 70 72 78 34 35  00 73 63 5F 70 72 78 34  36 00 73 63 5F 70 72 78   c_prx44.sc_prx45.sc_prx46.sc_prx
00000380   34 37 00 73 63 5F 70 72  78 34 38 00 73 63 5F 70  72 78 34 39 00 73 63 5F  70 72 78 35 30 00 73 63   47.sc_prx48.sc_prx49.sc_prx50.sc
000003A0   5F 70 72 78 35 31 00 73  63 5F 70 72 78 35 32 00  73 63 5F 70 72 78 35 33  00 73 63 5F 70 72 78 35   _prx51.sc_prx52.sc_prx53.sc_prx5
000003C0   34 00 73 63 5F 70 72 78  35 35 00 73 63 5F 70 72  78 35 36 00 73 63 5F 70  72 78 35 37 00 73 63 5F   4.sc_prx55.sc_prx56.sc_prx57.sc_
000003E0   70 72 78 35 38 00 73 63  5F 70 72 78 35 39 00                                                        prx58.sc_prx59.

这里我把数据分了一下段,这样便于更好的理解其含义

开头第一个DWORD,是0x3B等于十进制59,个人而言,看见这个数字的第一眼我就觉得它是FileCount。大部分的打包格式都会记录内含的文件数目,这个数目放在文件开头无疑是最方便后续处理的。当然,你也可以在最开头放上一个什么PKG的标记之类的,然后再加上一个MD5的Hash?

然后0x3B*4=0xEC。这时候可以注意到第三块的起始位置是0xD0,刚好是0xEC+4,然后0xD0+0xEC也和第四段数据起始位置吻合。
所以以此推断gtb的文件格式是这样的:
GTB FileFormat:
0x0              FileCount
0x4              FileNameLength[FileCount]
+FileCount*4     FileOffsetTable[FileCount]
+FileCount*4     FileNameTable

这里需要说的是第二段数据全部是每个文件的文件名的字符串长度,需要联合FileNameTable一起用的。
如果需要获取名为xxxxx文件,那么获取方法如下:

设lpmem为gtb在内存的存放起始位置

for (int i=0;i<FileCount;i++)
{
  if (strcmp(((lpmem+4+FileCount*4*2)+(lpmem+4+4*i)),xxxxx))
  {
    int FileOffset=*(lpmem+4+FileCount*4+i*4)+40h;
    int FileLength=*(lpmem+4+FileCount*4+i*4+4)-FileOffset;
    lpFile=VirtualAlloc(NULL,FileLength,PAGE_READWRITE,MEM_COMMIT);
    SetFilePointer(hGpk_File,FileOffset,FILE_BEGIN);
    ReadFile(hGpk_File,lpFile,FileLength,NULL,NULL);
  }
}
这里附加说明一下,这里的程序代码都是完全没有测试过的,只保证逻辑上应该没有问题,至于什么类型转换之类的未涉及。

关于40h的偏移修正解释如下:
我们以第一个文件为例:WinHex中的内容如下
00000000   50 4E 47 20 20 20 20 20  20 20 20 20 20 20 20 20  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   PNG             ................
00000020   23 E6 00 00 4A 01 00 00  50 00 00 00 20 20 20 20  50 41 43 4B 54 59 50 45  3D 38 41 20 20 20 20 20   #?.J...P...    PACKTYPE=8A     
00000040   89 50 4E 47 0D 0A 1A 0A  00 00 00 0D 49 48 44 52  00 00 01 4A 00 00 00 50  08 06 00 00 00 7F 13 3C   NG........IHDR...J...P.......<
00000060   4C 00 00 00 09 70 48 59  73 00 00 37 5D 00 00 37  5D 01 19 80 46 5D 00 00  0A 4D 69 43 43 50 50 68   L....pHYs..7]..7]..F]...MiCCPPh
00000080   6F 74 6F 73 68 6F 70 20  49 43 43 20 70 72 6F 66  69 6C 65 00 00 78 DA 9D  53 77 58 93 F7 16 3E DF   otoshop ICC profile..x?SwX.>?

如果你不使用40h的偏移修正,那么你保存出来的PNG是无法读取的。这时候最好的办法莫过于自己去把一个什么图转成PNG然后来对比。
对比之后你就会发现,所有的正确的PNG开头都是89504E47这样的。所以我们刚好切掉前面的20h,然后这样这个png就可以正确显示了。

4、cdvaw文件夹
同样的2种类型的文件vtb和vpk,看大小同样的一个是描述表,一个是文件数据集合。
但是vtb的格式略有不同:
00000000   61 61 30 32 30 30 30 31  00 00 00 00 61 61 30 32  30 30 30 32 D7 84 00 00  61 61 30 32 30 30 30 33   aa020001....aa020002..aa020003
00000020   53 ED 00 00 61 61 30 32  30 30 30 34 A4 51 01 00  61 61 30 32 30 30 30 35  1D 88 02 00 61 61 30 32   S?.aa020004..aa020005.?.aa02
00000040   30 30 30 36 22 B7 03 00  61 61 30 32 30 30 30 37  D3 DA 04 00 61 61 30 32  30 30 30 38 A3 57 06 00   0006"?.aa020007于..aa020008..
00000060   61 61 30 32 30 30 30 39  BB 26 07 00 61 61 30 32  30 30 31 30 05 4F 07 00  61 61 30 32 30 30 31 31   aa020009?..aa020010.O..aa020011
首先,vtb中没有FileCount,这使得在其中索引必须先构建一张索引表。
具体文件内容很简单:
CHAR FileName[8];
DWORD FileOffset;
每12字节为一个描述单位。最后以8个0+vpk文件总体积为结束。(什么文件大小?后一个文件的Offset减去自己的Offset不就是了么……)
我们依然以VPK中的第一个文件aa020001来说:
00000000   49 46 20 50 41 43 4B 54  59 50 45 3D 3D 32 20 20  43 55 54 20 54 48 49 53  20 31 30 38 42 59 54 45   IF PACKTYPE==2  CUT THIS 108BYTE
00000020   54 48 45 4E 20 52 45 4D  41 4B 45 20 4F 47 47 20  50 41 43 4B 54 59 50 45  3D 32 20 20 20 20 20 20   THEN REMAKE OGG PACKTYPE=2      
00000040   52 49 46 46 94 56 03 00  57 41 56 45 66 6D 74 20  10 00 00 00 01 00 01 00  44 AC 00 00 88 58 01 00   RIFF..WAVEfmt ........D?...
00000060   02 00 10 00 64 61 74 61  70 56 03 00 4F 67 67 53  00 02 00 00 00 00 00 00  00 00 77 7E 00 00 00 00   ....datapV..OggS..........w~....
00000080   00 00 9F 25 DF E6 01 1E  01 76 6F 72 62 69 73 00  00 00 00 01 44 AC 00 00  00 00 00 00 B1 AD 01 00   ..?哝...vorbis.....D?.....杯..
000000A0   00 00 00 00 B8 01 4F 67  67 53 00 00 00 00 00 00  00 00 00 00 77 7E 00 00  01 00 00 00 5E 90 85 5F   ....?OggS..........w~......^.
我们看见了开头无比嚣张的一段txt,但实际上Foobar2K告诉我,不管你前面不裁减掉还是裁减20h还是按它说得裁减到0x6c的位置,对播放都不是问题。文件格式依然是OGG。

5、spt文件夹
这个文件夹其实对于想汉化游戏的人来说才是重点。
首先Winhex中显示出来的数据完全无法理解,挂了Apploc的Notepad中也看不见任何日文文本。这时候我们就需要OD了
结果很恶劣,又是按字节Xor 0xFF(实际上是按DWORD xor -1,但实际上是一样的)祭出FileEncrypter和谐一下,再拖入Notepad就可以看见大片大片的日文文本了。
然后我们继续来看spt文件格式(由于我并不是想玩这个游戏,所以这个文件我就没去折腾,毕竟你是在面对一个解释引擎……)
1kyo.spt.decrypted
00000000   20 00 00 00 01 00 66 66  01 00 55 55 00 00 00 00  AE 08 00 00 84 F9 01 00  C8 0D 00 00 58 80 02 00   ?....ff..UU....?....?..X..
00000020   14 00 00 00 4E F6 01 00  03 00 00 00 00 00 00 00  53 50 54 48 45 41 44 45  52 30 20 20 20 20 20 00   ....N?.........SPTHEADER0     .

已知的信息:0x10,sizeof(Block1)/4,0x14, offset Block1/4,后面3个也是这样。
比如0x14的0x1F984*4=0x7E610:
0x020232  *4=0x0808C8  "???\n「いいこと、ぼうや\n よくおきき」 "
0x02023D  *4=0x0808F4  "???\n「むかぁし、むかしのおはなしです……」  "
0x020249  *4=0x080924  " キス——  "
0x02024C  *4=0x080930  " キス、たったいっかいだけで\n カエルはりっぱな王子さまに、 "

这个就是这样了,有空去把图片全部解出来……然后可以收工了。

论坛没有隐藏功能,为了祖国的花朵,我就把地址加个密好了。大家来解吧,解出来的千万别说哦!

下面的这个只是一个一个TXT的Hex,不是什么强力的加密……
FF978B8B8FC5D0D0888888D1989A8B9C978AD19C9092D08C90998BD18F978B9293C0969BC2C8CECCCACCC6D9989CC2989CF2F5978B8B8FC5D0D0989E929A8D8C8B9E8B9690918CD1919A8BD0CDCFCECED0CFC6D0CDCCD0CECECFC6CDCDDABACCDAC7CCDAC6C8DABACCDAC7CCDABEBEDABACCDAC7CCDABDCCDABACCDAC7CDDABDBDDABACCDAC7CDDABDC687D2DABAB9DABDBBDAC6BADABACADAC7CCDAC6CADABACCDAC7CEDABEBADABAC7DABEC7DABDCEDABACADABEBDDAC7CEDABACCDAC7CEDABEB9DABACCDAC7CCDABECDDABACCDAC7CCDABDCCDABACCDAC7CDDABDC6DABACCDAC7CDDABDB9DABACCDAC7CCDABDBCDABACCDAC7CEDABECCDABACADABEC7DAC6C7DABAB9DABDBBDAC6BAD2DABACADAC7C7DAC6BBD0FF

  • 标 题:答复
  • 作 者:无聊的菜鸟
  • 时 间:2011-09-27 20:09:00

好吧,我还是把dwq的解包工具发了吧。

由于是自己用的,所以没做的太人性化。

解包是没有问题的,有问题的是文件的后缀名。PNG文件没有问题,JPG会被写成JPE后缀,这个也不是什么问题。大部分BMP可以正确写出,.IF,.PAC文件也是BMP文件,其中有3个是无法读取的,但是基本上说,这几个文件都是材质。所以大家不用理会他们。

和谐和不和谐的东西全部是PNG……

VC2010编译,若无法运行,请自行搜索下载安装VC2010的运行包!

上传的附件 PrincessX_Unpack.rar