赞
踩
针对Cocos2dx-lua提供的轻量级加密方案的反编译。该博客参考自原文章
一般使用该轻量级加密方案的命令如下:
cocos luacompile -s 未加密源码目录 -d 加密后源码目录 -e -k 加密key -b 加密sign --disable-compile
要解密,那么需要知道的是加密key
和 加密sign
一、加密解密思路
我们将后缀为.lua的文件加密成.luac文件,然后放入apk中,那么在程序运行时,势必需要对.luac的文件进行解密,然后再加载运行文件。那程序是如何知道我们在加密key呢?有两个猜想:
1,加密key写入文件,程序在解密时先读取文件中的加密key,再解密。
2,加密key与程序内部约定某个值。
显然,第一种做法很不明智,key值直接存入文件很容易破解,那么就验证第二种做法,既然加密key是约定的,那么肯定可以在程序中找到该值。通过搜索发现验证了该想法。
在工程的frameworks\runtime-src\Classes\AppDelegate.cpp文件applicationDifFinishLauching方法中
能够看到设置了加密key和sign
二、反编译luac
要反编译.luac文件,需要知道加密key和sign。上面提供了一个思路,sign在.luac中寻找,key在打包后的libcocos2dlua.so中寻找。
1,寻找加密sign
用记事本打开某个.luc文件,文件开头的前几个字符即加密sign
2、寻找加密key
下载IDA(交互式反汇编器),将libcocos2dlua.so拖到该IDA快捷图标上,此时会弹出
选择 OK,等待加载function name,避免操作应用是卡住。等会后选择view/open subviews/strings
Ctrl + F 搜索 刚刚获取的sign(XXTEA),得到如下结果
点击该结果,在该结果的附近则能够发现加密key(2dxLua)
3、加密key,加密sign已经获取,如何反编译
cocos使用的XXTEA进行加密,其在external目录下,在xxtea.h可以看到,提供了加密解密方法
#ifndef XXTEA_H #define XXTEA_H #include <stddef.h> /* for size_t & NULL declarations */ #if defined(_MSC_VER) typedef unsigned __int32 xxtea_long; #else #if defined(__FreeBSD__) && __FreeBSD__ < 5 /* FreeBSD 4 doesn't have stdint.h file */ #include <inttypes.h> #else #include <stdint.h> #endif typedef uint32_t xxtea_long; #endif /* end of if defined(_MSC_VER) */ #define XXTEA_MX (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z) #define XXTEA_DELTA 0x9e3779b9 unsigned char *xxtea_encrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length); unsigned char *xxtea_decrypt(unsigned char *data, xxtea_long data_len, unsigned char *key, xxtea_long key_len, xxtea_long *ret_length); #endif
4、运行cpp文件,调用解密方法,解密.luac文件
win上运行cpp文件,可以按照MinGW MinGW,选择mingw-get-setup.exe
。选中里面的mingw32-gcc-g+±bin进行安装。安装完成后配置下环境变量,安装目录下的bin,例如D:\MinGW\bin
。
在cocos引擎external目录下复制一份xxtea.cpp和xxtea.h,修改xxtea.cpp的后缀名为xxtea.c,不知为啥,用.cpp后缀就是生成不了exe文件。然后编写一个入口文件,main.c
#include<stdio.h> #include<stdlib.h> #include<string.h> #include"xxtea.h" int main(int argc,char*argv[]){ FILE*fp; char*key; char*sign; char*infile; char*outfile; char*buf,*data; unsigned long size; int keylen,signlen,retlen; if(argc<5){ printf("usage:lua_decrypt infile outfile sign key\n"); return -1; } else{ infile=argv[1]; outfile=argv[2]; sign=argv[3]; key=argv[4]; keylen=strlen(key); signlen=strlen(sign); } if((fp=fopen(infile,"rb"))==NULL){ perror("can't open the input file"); return -1; } fseek(fp, 0L, SEEK_END); size=ftell(fp); rewind(fp); buf=(char*)malloc(size); fread(buf,size,1,fp); fclose(fp); data=xxtea_decrypt(buf+signlen,size-signlen,key,keylen,&retlen); if(data==NULL){ printf("%s decrypt fail\n",infile); return -1; } if((fp=fopen(outfile,"wb+"))==NULL){ perror("can't open the output file"); return -1; } fwrite(data,retlen,1,fp); fclose(fp); free(data); printf("%s decrypt successful\n",infile); return 0; }
将这三个xxtea.c xxtea.h main.c这三个文件放在同一个目录下,进入cmd,进入该目录下,键入
gcc xxteac main.c -o luac_decrypt
生成luac_decrypt.exe,然后将要解密的.luac文件放在该目录下,键入
luac_decrypt xx.luac xx.lua sign key
即可反编译.luac文件。
例如放置了version.luac文件在该目录,sign是XXTEA,key是2dxLua,即命令如下:
luac_decrypt version.luac version.lua XXTEA 2dxLua
即可以反编译后输出文件version.lua
三、扩展,批处理
每次都是命令行反编译一个文件,显示效率低效。可以编写批处理,设置luac文件夹,输出文件夹,反编译exe路径,sign,key,然后循环反编译luac文件夹下所有的.luac文件
rem "decompile Luac script" echo off rem set your luac direction set sourcePath=C:\Users\86181\Desktop\luac rem set your luac_decrypt.exe path set decryptPath=C:\Users\86181\Desktop\luac_decrypt.exe rem outfile direction set outfilePath=C:\Users\86181\Desktop\lua\ set suffix=.lua set sign=XXTEA set key=2dxLua md %outfilePath% for /r %sourcePath% %%i in (*.luac) do ( %decryptPath% %%i %outfilePath%%%~ni%suffix% %sign% %key% ) pause
一、.lua文件编译为字节码文件.luac
lua中自带将.lua文件编译为字节码文件,命令行luac -o 输出文件 源文件
在桌面新建文件夹aaa,放入源文件helper.lua命令行中执行
luac -o helper_luac.luac helper.lua
会在aaa文件夹下生成helper_luac.luac文件,用记事本打开该文件。
二、.luac文件反编译为.lua文件
下载unluac.jar包,官网地址
将下载后的包重命名为unluac.jar,并拖动到aaa文件夹下,执行命令java -jar unluac.jar helper_luac.luac>helper_decrypt.lua
(需要支持java命令),这时会在aaa文件夹下生成helper_decrpyt.lua,将原本的helper.lua与反编译后的helper_decrpyt.lua进行对比,发现除了某些格式,代码基本一致,反编译成功。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。