解密Cocos2D中的Lua源码
由于没学习和使用过Cocos2D,但出于工作需要,后面将要学习与使用Cocos2D。 第一次使用修改过的Cocos的时候遇到一些Lua文件是加过密的,不能看到源码,但是又可以正常的被Cocos读取执行,通过对Lua的调试可以看到读取到内存中的源码,由于调试工具的限制,无法直接将这些源码保存到磁盘,当然有一个笨办法,就是将能看到源码的文件一个一个地保存到磁盘,在没有更好的办法之前,也只能这样了。这样做有一个问题,就是如果有更新,又得重新来过,这样下去肯定是不行的。所以必须搞明白Cocos2D是怎么加载执行Lua的。
Lua有以下几个API加载执行:
- luaL_loadfile直接从文件中加载执行
- luaL_loadbuffer从内存中加载代码执行
- luaL_loadstring从一个字符串中加载执行
加过密的Lua文件一般不能直接使用luaL_loadfile来加载执行,那只能是后面两个API了。Cocos2D是开源,下载了一份源码,看了一下其调用Lua的方式确实是通过luaL_loadbuffer来加载执行的,可以看看源码:
1int CCLuaStack::luaLoadBuffer(lua_State* L, const char* chunk, int chunkSize, const char* chunkName)
2{
3 int r = 0;
4
5 if (m_xxteaEnabled && strncmp(chunk, m_xxteaSign, m_xxteaSignLen) == 0)
6 {
7 // decrypt XXTEA
8 xxtea_long len = 0;
9 unsigned char* result = xxtea_decrypt((unsigned char*)chunk + m_xxteaSignLen,
10 (xxtea_long)chunkSize - m_xxteaSignLen,
11 (unsigned char*)m_xxteaKey,
12 (xxtea_long)m_xxteaKeyLen,
13 &len);
14 r = luaL_loadbuffer(L, (char*)result, len, chunkName);
15 free(result);
16 }
17 else
18 {
19 r = luaL_loadbuffer(L, chunk, chunkSize, chunkName);
20 }
21
22#if defined(COCOS2D_DEBUG) && COCOS2D_DEBUG > 0
23 if (r)
24 {
25 switch (r)
26 {
27 case LUA_ERRSYNTAX:
28 CCLOG("[LUA ERROR] load \"%s\", error: syntax error during pre-compilation.", chunkName);
29 break;
30
31 case LUA_ERRMEM:
32 CCLOG("[LUA ERROR] load \"%s\", error: memory allocation error.", chunkName);
33 break;
34
35 case LUA_ERRFILE:
36 CCLOG("[LUA ERROR] load \"%s\", error: cannot open/read file.", chunkName);
37 break;
38
39 default:
40 CCLOG("[LUA ERROR] load \"%s\", error: unknown.", chunkName);
41 }
42 }
43#endif
44 return r;
45}
这个函数在执行luaL_loadbuffer之前有一个逻辑处理,看源码一切就明白了。再回过头来看看那些Lua文件,果然最前面都有几个一样的标记,这个标记就是加密标记。
知道了加密的标记和标记的长度是不够的,还必须要有解密的Key,这个Key怎么得到?直接运行用Cocos源码调试?貌似不行,前面说过,我使用的Cocos是修改过的Cocos,只有使用 OllyDbg或者 IDA来进行调试查找了。 网上有一篇文件有讲怎么查找Key: 《Cocos2d-x的lua官方加密的解密方法》,但这篇文章中的查Key方法只适合比较明显的,或者就是碰运气,我曾按这个方法去查Key发现不对。我是通过调试,在调用luaL_loadbuffer函数处和前面不远的地方打断点,通过调试获取到的Key。我这种方法也只适合Lua是在Dll中执行,调用luaL_loadbuffer之前不远的地方调用xxtea_decrypt,如果是两个差得比较远或者是把Lua链接进主程序也不行。
知道Key了就好写解密程序了,直接把Cocos中的xxtea_decrypt函数拿出来解即可,也可以去 https://github.com/cocos2d/cocos2d-x-3rd-party-libs-bin/tree/v3/xxtea下载。
- 原文作者:Witton
- 原文链接:https://wittonbell.github.io/posts/2018/2018-05-26-解密Cocos2D中的Lua源码/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. 进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。