不过别的部分呢?我们还是回到那个只存储了10个文件的.bin文件。文件名之前的全部字节都搬出来四个一组地放好:
0A 00 00 00 5B 00 00 00 00 00 00 00 DB 00 00 00
BC EB 11 00 09 00 00 00 97 EC 11 00 2C 08 13 00
12 00 00 00 C3 F4 24 00 B9 99 11 00 1B 00 00 00
7C 8E 36 00 33 9E 0B 00 25 00 00 00 AF 2C 42 00
75 05 15 00 2E 00 00 00 24 32 57 00 67 DD 14 00
37 00 00 00 8B 0F 6C 00 FC FC 14 00 40 00 00 00
87 0C 81 00 DC 2C 15 00 49 00 00 00 63 39 96 00
3C 06 15 00 52 00 00 00 9F 3F AB 00 AC 23 15 00
回忆一下教程内容:这一部分文件头可能会包含文件签名、索引大小、文件条目列表(文件名,起始位置,文件大小,等等)。第一行第一个确认是文件字数,之后的部分呢?观察发现,到第一行第四个的DB 00 00 00正好是我们第一个hzc文件的偏移(同理,注意到D9 01 00 00 也是第一个ogg文件的偏移)。然后跟着的是0011EC97的位置:【图一】
没错,正是hzc文件的文件头。所以以此类推,从DB 00 00 00开始,每隔两组数字即出现下一个文件的索引。wxMEdit可以显示当前选定的字符的位置,于是我们看看两个hzc文件头间隔了几个字符(这个信息给我们看的,所以当然是十进制数):
1174679 - 219 = 1174460 = 0x11EBBC
这个是第一个hzc文件的大小,也正好是第五组小端序整数表示的值。以此类推。是不是还剩下一些比较小的数?这些,我们不妨直接说出来,除了5B 00 00 00以外,表示的是文件名相对于“开始写入文件名的位置”的偏移。而0x5B=91 则是∑[文件数]*[文件名+1],最后的+1是算上了0x00,这个位置是当作间隔符来用的。
那么我们可以总结.bin文件的文件头究竟是怎么构成的了:
1.四个字节的小端序整数,记录包含的文件数目
2.四个字节的小端序整数,记录文件名总长度(包括0x00的间隔符)
3.每个文件占12个字节三个四字节小端序整数,记录了:
3.1文件名相对于开始写入文件名位置的偏移
3.2文件本身相对于归档文件开头的偏移位置
3.3文件大小
4.列出所有文件名,以0x00为分隔
如无意外,我们可以推断“开始写入文件名位置”应当是4+4+12x(假设x为第一个小端序整数也即文件数),而“开始写入文件”则在4+4+12x+y的位置。写入的文件可能被压缩但没有加密,可能有“hzc1”“OggS”“RIFF”这三种文件头(分别对应压缩过的图片文件.hzc文件,未压缩的音频文件.ogg文件,未压缩的音效文件.wav文件)。知道了这些,我们就可以自己写一个解包程序,或者直接让D指导代劳:【图二】
然后运行一下。这里我们用cmd即可:
Win+R,cmd,python
网页链接 输入待解包文件名
网页链接 输入输出路径output
已提取:output\
网页链接 ……
已提取:output\
网页链接 好,提取完成。为验证效果,开游戏试试。一般来说标题界面bgm是02.ogg,总之听一听(读者可以用GARbro解包之后对比效果)。
很好,完全一致,说明我们的解包程序是成功的。换个游戏试试?这次用樱花摸鱼的文件看看行不行。结果是也能行。妙哉妙哉。不过输入两次还是太麻烦了,干脆改一改:
input_file = input("输入待解包文件名:")
output_dir = input_file.replace(".bin","")
这回方便多了。
(未完待续)

