欢迎光临散文网 会员登陆 & 注册

galgame解包(封包)记录Ⅱ

2023-09-02 12:49 作者:一ノ瀬秋乃  | 我要投稿

前言

前两天闲来无事,想找个引擎摸摸。本来想摸bgi的,结果一看封包,瞪眼法全看出来。遂换了个目标,找了个没什么人引擎来摸。

研究的游戏叫《あおぞらストライプ》,p口水的早期作品

游戏cg


出品会社叫アストロノーツ・コメット。这个社还出过《付喪女・あおゑ》等作品,这里安利一下《付喪女・あおゑ》的op《AIRI 愛離》,非常好听。p口水另外还有部叫《えれくと!》的作品,是其一个姐妹社アストロノーツ・スピカ开发的(应该吧)。《あおぞらストライプ》和《えれくと!》使用的都是同一款引擎,可以互相套用。

正文

游戏除了exe,就只有几个后缀为gxp的文件,毫无疑问这就是游戏的封包。

010Editor打开文件看一下

bgms.gxp

选观察对象的时候尽量选可以猜到文件数的(当然如果封包名和gbi那种一样就算了),这样可以比较方便分析。

很明显数据从0x30开始变得杂乱。所以我们先看看前0x30个字节。

最像文件数的毫无疑问是0x18,当然我们并没有办法保证。

多对比几个封包,会发现几个封包的前6个DWORD是一样的。说明他并没有描述封包数据。我们暂时不关心。

如果你足够仔细的话,可以发现0x20开始,两个QWORD的和就是这个封包的size。而0x28处的QWORD都是0x1C处的值+0x30。

这基本是我们现在能从封包获得的全部信息。剩下的就是

直接断CreateFile,值得一提的是这引擎用的是W系的API,可以说是领先业界了。

断点命中后往回跟几层。可以发现函数明显长得像fopen。

最后我们可以看到

此时可以得出该封包封包头的大致结构

struct GxpArchiveHeader

{

char mgaicNumber[4] = { 0x47,0x58,0x50,0x0 }; //封包文件头

DWORD engineInfo[5] ; //未知,可能是引擎的版本信息之类的东西吧

DWORD entryCount ; //封包文件数,或者说是目录项数

DWORD contentsSize; //封包目录的大小,目录项的大小不是固定的

QWORD dataSectionSize; //数据区域大小

QWORD infoSectionSize; //封包头+封包目录大小

};


0x30的封包头过头就是封包的目录部分。值得一提的目录项的大小是不固定。

目录部分和目录部分都是有加密的(一个比较简单的异或),但是解密会用到一个17字节的表,引擎版本不同这个表可能会不同吧

对于每个目录项,程序会先解密它的前4个字节,该DWORD记录了整个项的大小。随后再解密剩余部分。

数据就更简单了,用同样的方法解密一次就可以了

目录项的结构大概为

struct GxpContentsEntry

{

DWORD entrySize;

QWORD dataSize;

DWORD fileNameLength;

QWORD unknow;

QWORD offsetInDataSection;

WCHAR fileName[];

};


以system.gxp为例


唯一的目录项
system.gxp的size


目录项里有个被我标注成了unknown的成员,不知道那是个什么东西。看着不像哈希之类的玩意,程序好像也没有用。

如果尝试直接塞0然后封包的话,游戏也能正常运行。所以就不管它了吧

封包测试


总结

总的来说这个引擎的封包结构还是非常简单的,只不过数据套了层加密而已。

游戏的文本在bincode.gxp里,之后有时间可能会研究。

之前看到一个叫《星降る夜のファルネーゼ》的游戏,那个游戏的封包看起来比较炫酷,有时间可能会看看

《星降る夜のファルネーゼ》的封包


galgame解包(封包)记录Ⅱ的评论 (共 条)

分享到微博请遵守国家法律