一、首先看package.ini文件
[SO3Client]
11=data_6.pak
10=data_5.pak
1=ui.pak
0=update_1.pak
3=maps.pak
2=settings.pak
5=scripts.pak
4=represent.pak
7=data_2.pak
6=data_1.pak
9=data_4.pak
Path=.\pak
8=data_3.pak
这里显示了所有Pak文件,索引数越小,表示等级越高,如果某个文件在update_1.pak和ui.pak中都存在,则以update_1.pak中的为准。
二、分析每个Pak文件
Pak文件的前16个字节格式如下:
[pak标记(Uint32)(PACK)] + [文件数目(Uint32)]+[索引数据在文件中的偏移位置(Uint32)]+0x20000000。
由此可以读出索引数据(在每个文件的最后面)。
每条索引数据16个字节,格式为[哈希数值(Uint32)] + [数据在文件中的偏移位置(Uint32)]+[解压后文件长度(Uint32)] + [文件在pak中的长度(Uint24)]+[压缩标志(1Byte)]。
其中,压缩标志有三种:0x20压缩,0x00未压缩,0x10未压缩(是某种未知格式,不需解压)。
三、解压注意事项
每个文件都有唯一对应的Hash,计算的函数在Engine_Lua5.dll中的g_FileNameHash,注意传递的文件路径必须以“\”开头,DWORD g_FileNameHash(char*)。
解压函数也在Engine_Lua5.dll中,位置是DLL基址+0x18020,int 函数名(char* pSrcData, int nSrcLen, char* pDstData, int* pDstLen)。
至于文件名,可以用FileMon得到一部分,再通过分析得到的文件内容得到更多。