第六章 脚本解包

您所在的位置:网站首页 加密pvf内存不足 第六章 脚本解包

第六章 脚本解包

#第六章 脚本解包| 来源: 网络整理| 查看: 265

工欲善其事, 必先利其器.

游戏大多数逻辑都是在客户端处理的, 所以DFO单机版大多数时间都是在DIY客户端的pvf脚本.

手中只有1个1年多之前的100级pvf, 拖入Winhex中查看发现文件头和台服的一模一样.

贴吧有人发过台服pvf解包分析, 文件头最前面的guid是脚本的版本号, 难道这么多年了版本号竟然一直没变? 多年前的pvf解包工具竟然还能解包最新版本的脚本?

按照经验, 无论脚本如何加密, 因为游戏引擎只能解析明文数据, 所以脚本在内存中某一时刻必然以解密后的明文形式出现。 为了游戏性能考虑, 一旦解密成功, 这些明文极大可能会长久存在于内存中。  这些明文就是分析解包算法的关键.

可是在游戏中用CE搜索, 无论搜索包头的版本号, 还是解密后的脚本头#PVF_File, 甚至未反编译的二进制脚本, 全都搜索不到结果.

但是看贴吧里很多人都有最新版本的pvf脚本解包文件, 说明要么解包算法极其简单, 要么就是有人做出了工具在小范围内部流传. 加了几个群, 群文件里全都是只有我手中那个去年的100级解密后的脚本,  解包工具就更别想了.

一时没有好的解包思路, 正准备硬着头皮还原算法,  忽然发现早在几年之前就有大神发了新版的解包源码.

佩服大神的逆向功底, 更佩服大神的开源精神!

立马上游戏开CE对着大神的源码分析游戏代码, 发现虽然过了几年但不仅解密算法没变, 就连解密秘钥都一模一样!

用最新的pvf试了一下确实成功解包了.

看了源码之后对之前的所有的疑问豁然开朗: 并不是前朝的剑能解当朝的包, 我手中那个可以用pvfUtility正常分析的pvf脚本是别人解包100级脚本之后把明文脚本按照台服pvf格式重新打包回去的, 重新打包时用了旧版的版本号. 新版pvf中已经没有旧版那种guid版本号了. 旧版明文脚本开头的B0 D0文件头标识也没有了, 所以在游戏中二进制搜索明文也搜不到.

大神的源码中只有解密算法和解包代码, 并没有加密算法以及封包代码. 虽然根据解密代码还原出封包的代码不算难, 但一想到每次即使只修改1个字节也要封包重启游戏就头大, 这样的修改显然不够效率. 良好的修改流程应该是所见即所得的, 像动态加载nut代码一样, 修改后即时生效.

之前提到过在服务器的代码中存在一个变量可以让服务器直接加载解包后的散装脚本, 服务端代码载入脚本统一使用loadRDARScriptFile函数, 相应的客户端肯定也应该存在这样一个函数, 参数是脚本的相对路径, 返回解密后脚本的二进制明文. 在解密函数下断点通过函数调用栈很容易找到客户端的loadRDARScriptFile.

找到加载脚本的函数之后, Hook这个函数, 做的第一件事是dump脚本. 这个函数内部会解密解压缩脚本密文数据, 之后找个恰当的时机把明文脚本按照路径dump到客户端Script目录下.这样第一个好处是解包工具就不需要再写了,另一个好处是在这里打印日志之后, 可以立即显示游戏中每个操作需要对应加载的脚本, 方便修改.

散装脚本dump下来之后, 二进制脚本的反编译很容易, 只需要关心3种数据: 整数、浮点和字符串, 简单写个几十行代码的python脚本做二进制脚本的编译和反编译就可以了, 杀鸡就不用 pvfUtility这种牛刀了.

Hook loadRDARScriptFile最重要的功能就是可以加载本地未封包的散装脚本文件. 在dump明文脚本的地方,  判断如果要加载的脚本在本地存在, 直接把解密后的明文数据用本地明文脚本文件做替换就可以了.

通过打印日志可以发现同一个脚本是会被游戏多次加载的, 这就给了动态修改脚本提供了可能. 找到游戏中动态加载脚本的函数, 可以尝试定期主动调用来刷新已加载的脚本.

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3