剑3资源格式分析(仅用于学习和技术研究)(一)

剑3资源格式分析(仅用于学习和技术研究)(一)
   这几天在玩剑三,突然兴趣来了,想要分析剑3的资源打包格式。在资源分析和逆向方面原来偶尔也干过,
不过总体来说还是处于菜鸟阶段,这篇文章希望和其他有兴趣的兄弟分享下这几天的经历,仅仅作为技术研究。


一、安全保护

  一般来说,很少有游戏的资源格式可以直接通过分析资源文件本身得到答案,大部分难免要静态逆向、动态调试。
无论是静态逆向还是动态调试,首先需要知道当前exe和dll的保护情况,用peid查看,发现只有gameupdater.exe 用upx加壳了。不太明白金山为什么对客户端没有加壳。
其实我并不关心gameupdater.exe 是否加壳,毕竟要动态分析的目标是JX3Client.exe ,要动态调试JX3Client.exe,首先要解决启动参数问题。

二、启动参数

  如果直接启动JX3Client.exe,JX3Client.exe会直接退出,并启动gameuodater.exe,然后通过gameupdater.exe启动JX3Client.exe。
这种启动方式会影响动态调试,所以首先我需要找出JX3Client.exe的启动参数。打开IDA逆向,转到启动处,汇编代码如下:
start proc near
call    ___security_init_cookie
jmp     ___tmainCRTStartup
start endp
这是一个典型的VC程序入口,在___tmainCRTStartup 里,crt会初始化全局变量、静态变量,然后进入main,我们需要做的是直接找到main,
跟进去,会发现IDA已经帮我们找到WinMain了,直接跟进去,
关键代码在WinMain的入口处:
剑3资源格式分析(仅用于学习和技术研究)(一)_第1张图片
从这个代码片段可以知道,WinMain开始就比较了命令行参数是否是"DOTNOTSTARTGAMEBYJX3CLIENT.EXE ",如果不是,
则转到启动更新程序了。这个好办,我们写一个run.bat,内容只有一行:
JX3Client.exe DOTNOTSTARTGAMEBYJX3CLIENT.EXE
运行,果然,直接看到加载界面了。

三、PAK文件管理

  在剑3里,PAK目录下有很多PAK文件,剑3是通过package.ini 来加载和管理pak内部文件的。
这个文件内容如下:
[SO3Client]
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目录下所有的PAK文件都列出来了,其实剑3的资源文件打包方式基本上和新剑侠情缘类似(细节还是有比较大的差别)。
打开ollyDbg,带参数启动JX3Client.exe,在CreateFile设置断点,可以发现,package.ini 的读取和处理是在
Engine_Lua5.dll 的g_LoadPackageFiles 函数,熟悉新剑侠情缘资源管理方式的同学大概会猜到这个函数是做什么的,先看看函数内容吧,这个函数比较长
只能逐步的分析了,首先是打开ini文件
剑3资源格式分析(仅用于学习和技术研究)(一)_第2张图片
使用g_OpenIniFile打开前面提到的ini文件,如果打开失败,自然直接返回了。
打开成功后,循环读取ini配置的文件,读取的section是SO3Client 读取的key是0到0x20。

loc_1001119A:           ; int
push    0Ah
lea     ecx, [esp+1A0h+var_178]
push    ecx             ; char *
push    ebx             ; int
call    ds:_itoa        ; 这是根据数字生成key的代码
mov     edx, [ebp+0]
mov     edx, [edx+24h]
add     esp, 0Ch
push    40h
lea     eax, [esp+1A0h+var_168]
push    eax
mov     eax, [esp+1A4h+var_184]
push    offset unk_10035B8C
lea     ecx, [esp+1A8h+var_178]
push    ecx
push    eax
mov     ecx, ebp
call    edx             ; 读取INI内容 readString(section, key)
test    eax, eax
jz      loc_1001127A

这段是通过readString("SO3Client", key)来获取pak文件名, key就是"0"~"32"的字符串,也就是最多能配置32个Pak文件。
获得了pak文件名后,下面就是打开和保存pak文件的索引数据了。
剑3资源格式分析(仅用于学习和技术研究)(一)_第3张图片
后面的注释是我分析的时候加上的,IDA这个功能不错!
首先new一个0x20字节的空间用来存储pak对象(我自己命名的类),接着调用构造函数,创建pak对象。
创建对象后,要用这个Pak对象打开对应的pak文件了,这是我们下面的代码:
剑3资源格式分析(仅用于学习和技术研究)(一)_第4张图片
首先通过
mov     [edi+edx*4], eax
将对象保存,然后,调用这个类的成员函数打开pak文件,具体代码在sub_10010ca0。
剑3资源格式分析(仅用于学习和技术研究)(一)_第5张图片
这段代码的意思很明白了,打开文件,读取0x20的文件头,
剑3资源格式分析(仅用于学习和技术研究)(一)_第6张图片

这里做的是验证文件格式,和一些必要的验证。
剑3资源格式分析(仅用于学习和技术研究)(一)_第7张图片
这段是读取pak内部文件数目,读取索引数据,以备后面查询使用。
到此为止,所有pak文件的管理对象都已经加载和设置完毕了。
以上内容看起来很顺理成章,但是实际上凝聚了无数的失败和重试。
后面是pak内部文件的查找和读取了。
剩下的内容明天贴了~~~


你可能感兴趣的:(剑3资源格式分析(仅用于学习和技术研究)(一))