cocos2dx 3.12 各平台资源加密解密

时间:2021-10-08 09:35:05

前言,一般项目发包基本会加密 lua代码图片资源,现在3.12自带一套加密解密流程,但是这套加密流程只适用于lua代码解密,现在需要对框架进行修改,从而可以解密图片资源。

准备,首先要想好自己的加密解密的密钥文件头签名
{

如: 
String key = "KEY_FOR_ENCRYPT_OR_DECRYPT";
String Sign = "SIGN_FOR_ENCRYPT_OR_DECRYPT";

}

加密流程,先将lua代码和图片资源进行加密,可以写批处理方法,使用刚才想好的密钥和签名调用cocos2d-x/external/xxtea/xxtea.cpp里面的加密方法(这个加密方法可以改成我们自己的, 同理解密也可改)。将需要加密的lua代码和图片资源进行加密即可。最好可以批处理文件。(注:函数参数不用去改它的)
cocos2dx 3.12 各平台资源加密解密

cocos2dx 解密流程

1,首先要在Classes/AppDelegate.cpp里面设置解密密钥

applicationDidFinishLaunching(){

...

LuaStack* stack = engine->getLuaStack();
String key = "加密Key"; //想好的密钥
String Sign = "文件头签名"; //想好的签名
stack->setXXTEAKeyAndSign(key, strlen(key), Sign, strlen(Sign));

...
}

实际上就是将密钥和签名设置进去了CCLuaStack,可以用这些去解密lua文件代码 ,如下

cocos2dx 3.12 各平台资源加密解密

(注:如果不做图片的加密,这一步做完lua代码的解密就已经完成了)

2,可以看下lua自带的代码解密流程,实际上就是加载Lua代码的时候CCLuaStack调用CCFileUtil去调用各个平台的FileUtil的GetContens函数,获取文件内容buff,然后在CCLuaStack里面在调用LoadBuff()将解密后的内容buff进行加载的解密流程 (此过程cocos2d 3.12已经自带,所以文章开头说lua代码可以做到自动解密) 如下:

CCLuaStack.cpp
int LuaStack::executeScriptFile(const char* filename)
{
...

//调用各平台的获取文件Utils
FileUtils *utils = FileUtils::getInstance();

std::string fullPath = utils->fullPathForFilename(filename);

...
//拿到了文件的**内容buff**, data
Data data = utils->getDataFromFile(fullPath);
int rn = 0;

if (!data.isNull()) {
//**luaLoadBuffer**此函数就是lua解密函数
if (luaLoadBuffer(_state, (const char*)data.getBytes(), (int)data.getSize(), fullPath.c_str()) == 0) {
rn = executeFunction(0);
}
}
return rn;
}

lualoadBuffer如下,红线圈的部分就是解密过程,调用了我们在AppDelegate.cpp设置的密钥进行内容buff的解密,当然,只有判断出文件头是我们设置的签名才会进入这个函数进行解密,其他没加密的文件走else里面的语句,直接加载lua代码
cocos2dx 3.12 各平台资源加密解密

3, 接下来我们想让图片也支持解密,同理,我们可以通过lua解密加载流程推测出 加载图片的时候,肯定会调用FileUtil里面的GetContents获取文件的内容buff,然后通过内容buff进行图片的加载。那么我们需要做的就是->找到获取这个图片内容buff加载的地方(修改各个平台的调用函数),判断如果是加密过的内容buff那么就将内容buff解密了,然后在return回去,binggo!

想要获取图片加载 “内容buff” 的流程,我们可以在从Sprite::create打个断点,一步步跟下去,看看堆栈过程。

...

最终可以发现堆栈过程
FileUtilsWin32::getContents
Image::initWithImageFile
TextureCache::addImage
Sprite::initWithFile
Sprite::create

...

那么可以总结:
CCImages的initWithImageFile()函数
CCImages的initWithImageFileThreadSafe()函数
上面两个是加载图片读取文件内容buff的

还有另外一个CCFileutils里面的getValueMapFromFile()读取文件字典(plist等)
即是CCSAXParser.cpp里面的parse()函数读取内容buff来加载plsit
...

因此我们只需要将上面的3个函数加点料,即可实现解密 - -!

...

4,CCImages的修改如下 (图片加载文件地方)
先包含头文件:
cocos2dx 3.12 各平台资源加密解密
然后修改initWithImageFile()函数
cocos2dx 3.12 各平台资源加密解密
然后修改initWithImageFileThreadSafe()函数
cocos2dx 3.12 各平台资源加密解密

5, CCSAXParser.cpp的修改(字典类文件读取地方)
cocos2dx 3.12 各平台资源加密解密

6, CCBundle3D.cpp的修改(.c3b文件读取地方)
cocos2dx 3.12 各平台资源加密解密

7, CCFileUtil.cpp的修改(.json文件读取地方,所有getStringFromFile需要解密的地方)
cocos2dx 3.12 各平台资源加密解密

总结:至此图片解密也可以做到啦,其他粒子特效,图集文件,字体文件…. …. 的加密,是否可以通过找到加载文件内容buff的地方,然后对这个内容buff修改而达到解密的目的呢,留给大家去猜想和试探了!啊哈哈哈哈