花吻在上吧 关注:68,767贴子:742,845

【考古】花吻老引擎资源解析

只看楼主收藏回复

继续<del>水贴</del>考古,这次是老引擎的花吻相关的。
之前在整驯兽组的TTS模型,想着把原版的脚本拆出来用来打标,便去翻老贴看看有没有相关的教程。
拆包用的工具不外乎通用的GARbro或早期用的crass,以及当年移植组专门为老引擎花吻写的小工具。
GARbro能很好地将图像等资源拆出来,也能在给出密码的情况下将脚本文件拆出来,但得到的脚本文件并不是适合人阅读的形式,也没有将拆出来的资源封装回去的功能。
其他的古老的工具,一些只有部分功能可用,一些只留下了源码而且缺库编译不起来。
而资源文件结构相关的,只能从一些论坛中找到当年人们探讨时留下的零碎的信息,并没有较为详细的说明文档。
故书此贴以说明之,诸君有拆包、封包等需要的,或可以此为参考。
------
玲绪大人镇楼


IP属地:广东1楼2025-02-25 14:24回复
    本层备用。
    用来放参考文献之类的链接。


    IP属地:广东来自Android客户端2楼2025-02-25 14:27
    收起回复
      2025-08-04 19:30:23
      广告
      不感兴趣
      开通SVIP免广告
      顺便分享一波打标文件。
      给第3作和第5作里驯兽组的语音打的标,音频标识加入了表示作品编号的前缀。
      https://huggingface.co/datasets/Wanlau/HANAVoice


      IP属地:广东3楼2025-02-25 14:45
      回复
        分析工作由D指导完成。


        IP属地:广东4楼2025-02-25 14:47
        回复
          资源结构简述
          老引擎花吻中,我们所需的常规的资源大致有以下三类,图像资源、音频资源以及脚本资源,这些资源被封装在文件头为『FJSYS』的包中。
          其中音频资源通常为ogg格式,拆出来就可以直接听。
          图像资源通常为MGD格式,拆出来后可能还需要转换成常见的格式才能看到。
          而脚本资源则是经过加密的,拆包时需要配合密钥进行解密才行。
          而且拆出来的脚本虽然能直接看到台词、立绘标识等信息,但并不适合阅读,可能还需要进一步处理才能转化为适合阅读的形式。


          IP属地:广东5楼2025-02-25 18:03
          回复
            这么追到你了


            IP属地:上海来自Android客户端6楼2025-02-25 18:57
            收起回复
              拆包过程中,我们通常关注的是,其中有哪些文件,各个文件的偏移量和大小是多少。
              偏移量对应了文件在包中的位置,提取文件的过程就是从第{偏移量}个字节开始,读取{文件大小}个字节。
              ---
              接下来,尝试分析fjsys的文件结构。
              图中以BGM文件为例,各数据的英文名来自GARbro代码里的变量名。
              如无特别说明,默认字节顺序为小端序。
              开头的`46 4A 53 59 53`为文件头『FJSYS』。
              后面0x08到0x0B的4字节数据的意义暂时不清楚,0x0C开始的4字节数据为文件名区域大小(names_size),再往后的4字节数据为文件数量(file_count)。
              其后一部分为空,从0x54开始为文件索引,各个文件对应的索引为16字节数据,其中前4字节的数据为文件名相对偏移(name_offset),其后的4字节数据为文件大小(size),剩下的8字节的数据为文件偏移(offset)。
              文件索引后面紧跟着的为各个文件的文件名,文件名之间以字节`00`隔开。
              结合names_size读取了文件名部分数据后,配合前面的文件名相对偏移以及用作分隔的字节`00`,可得到各个文件的文件名。
              这样,我们就得到了一个列表,其包含了各个文件的文件名、文件偏移及文件大小的信息。
              根据这些信息,我们可以把fjsys包中的文件提取出来。
              图中的是HANA01的BGM文件,从中可提取出5个ogg音频文件。



              IP属地:广东7楼2025-02-25 20:48
              收起回复
                虽然不懂 但大受震撼(发出了不得了的声音)


                IP属地:辽宁来自Android客户端8楼2025-02-25 22:09
                收起回复
                  2025-08-04 19:24:23
                  广告
                  不感兴趣
                  开通SVIP免广告
                  fjsys包里的.MSD文件是被加密的,拆包后需要解密才能得到原始的.MSD文件。
                  加密过程如下,将原文件划分为32字节大小的数据块(末端不足32字节则剩余部分单独成块),根据主密钥及数据块编号得到该数据块的密钥,对其求MD5哈希值,可得16字节的字节串,转为对应的十六进制数码字符串则为32字节,将其与原数据块进行异或运算以完成加密。(数据块不足32字节则截取哈希值前部相应长度部分进行异或。)
                  对加密后各个数据块使用与加密时相同的密钥产生的哈希值进行异或运算,则可得原始数据。
                  要解密.MSD文件,首先需要知道其主密钥。对于花吻来说,主密钥就是对应作品的名称,如HANA01的主密钥就是『その花びらにくちづけを』。
                  然后,将.MSD文件划分为32字节大小的数据块(末端不足32字节则剩余部分单独成块)。
                  对于各个数据块,其密钥为主密钥与数据块编号的字符串拼接,注意文本的编码为『shift_jis』。(有些地方,其被称为『cp932』)
                  正如上面所说,对其求MD5哈希值,转为对应的十六进制数码字符串的形式,与数据块的32字节数据进行异或,则可得到原始的数据。
                  将解密后的各个数据块拼接起来,就能得到解密后的.MSD文件。
                  使用文本编辑器打开解密后的.MSD文件,编码选择『shift_jis』,若能看到『MSCENARIO FILE 』的文件头、各个立绘标识、音频标识以及台词,则说明该.MSD文件被成功解密。
                  解密后的.MSD文件仍不太好读,要转换成适合阅读的形式还需要进行进一步的处理,这部分留到以后再说。


                  IP属地:广东9楼2025-02-25 23:33
                  回复
                    悲报,超过当天限定数目后,网页端回贴就不加经验了,所以图像相关的部分明天再水。


                    IP属地:广东来自Android客户端10楼2025-02-25 23:37
                    回复
                      大佬,请问18和22有原始文件吗?不想用renpy引擎的


                      IP属地:湖北11楼2025-02-26 13:40
                      收起回复
                        关于图像资源的处理
                        老引擎花吻的图像资源通常为MGD格式,开头的`4D 47 44 20 `即为文件头『MGD 』。
                        其后的2字节数据为文件头部区域大小,0x0C开始的2字节数据为图像宽度,其后的2字节数据为图像高度。
                        0x10开始的4字节数据为解压后文件大小(疑似转换为位图格式后的文件大小),0x14开始的4字节数据为文件主体部分区域大小,0x18开始的2字节数据为压缩模式。
                        文件头部区域后即为文件主体部分区域,其开头的4字节数据为文件大小,其后便是文件本身的数据。
                        图像处理流程为,先读取文件头部获得文件头部区域大小、压缩模式等信息,再从文件主体部分区域的开头读取4字节数据获得文件大小,再于其后读取相应大小的数据,并根据压缩模式等信息进行解压及构建图像。
                        通过阅读GARbro的代码,我们知道其能处理的压缩模式有3中,为`0`、`1`和`2`。
                        以花吻1里的图像为例,示例图像的文件头部区域大小0x5C,图像宽度为0x0320即800像素,图像高度为0x0258即600像素,压缩模式为`2`,文件大小为0x0D8FE3,从0x60开始为文件本身的数据。
                        模式2即把图像以png格式存储,可以看到,示例从0x60开始的8个字节为`89 50 4E 47 0D 0A 1A 0A `,这是png文件头的特征。
                        处理时,只需要从文件本身的数据的开头起,读取相应文件大小的数据,即可得到一png格式的图像。


                        IP属地:广东12楼2025-02-26 22:00
                        收起回复
                          模式0中的图像数据以BGRA32格式存储,即每个像素的数据皆为4字节(32位),依次为B(蓝)、G(绿)、R(红)、A(透明度),处理时直接读取即可。
                          第19、20、21作的部分图像是以此模式存储的。(看文件大小能大致看出来,800x600像素的32位色的图像文件大小约为1876kB。)


                          IP属地:广东13楼2025-02-26 22:02
                          回复
                            模式1在花吻中没有用到,其形式是根据GARbro的代码猜测的。
                            这个模式中的图像数据是被压缩过的,其文件主体部分还可再分为透明度通道部分和色彩通道部分,这两部分开头的4字节数据皆为对应数据区域大小,其后则为数据本身。
                            透明度通道部分有两种模式,为RLE压缩模式以及原始数据模式;色彩通道部分有三种模式,为增量编码模式、重复像素模式以及原始数据模式。
                            因为没在花吻中用过,就不细究其处理过程了。


                            IP属地:广东14楼2025-02-26 22:03
                            回复
                              2025-08-04 19:18:23
                              广告
                              不感兴趣
                              开通SVIP免广告
                              余以为0x18开始的2字节数据为压缩模式,而GARbro的代码是读取0x18开始的4字节数据作为压缩模式的,但19作里的0x1A开始的2字节数据不为0,导致其无法正确被GARbro识别。这可能是旧版GARbro拆不了19作的MGD的原因。
                              新版的GARbro是能正常拆19作的,但这部分代码却还是没改?可能是在其它地方实现了类似的修复??


                              IP属地:广东15楼2025-02-26 22:03
                              回复