cocos2d-lua compile加密

  1. usage: cocos luacompile [-h] [-v] [-s SRC_DIR_ARR] [-d DST_DIR] [-e]  
  2.                         [-k ENCRYPTKEY] [-b ENCRYPTSIGN] [--disable-compile]  
  3.   
  4. 对 lua 文件进行加密和编译为字节码的处理。  
  5.   
  6. optional arguments:  
  7.   -h, --help            show this help message and exit  
  8.   -v, --verbose         更多输出信息。  
  9.   -s SRC_DIR_ARR, --src SRC_DIR_ARR  
  10.                         指定需要编译的 lua  
  11.                         文件路径,支持指定多个路径。  
  12.   -d DST_DIR, --dst DST_DIR  
  13.                         指定输出文件的路径。  
  14.   -e, --encrypt         开启 XXTEA 加密功能。  
  15.   -k ENCRYPTKEY, --encryptkey ENCRYPTKEY  
  16.                         指定 XXTEA 加密功能的 key 字段。  
  17.   -b ENCRYPTSIGN, --encryptsign ENCRYPTSIGN  
  18.                         指定 XXTEA 加密功能的 sign 字段。  
  19.   --disable-compile     关闭编译为字节码的功能。

    我们主要用到-s,-d,-e,-k,-b以及--disable-compile这几个参数:

    -s就是你需要加密的lua脚本所在的目录。

     -d就是逆需要将加密后的lua脚本放置的目录。

     -e是开启XXTEA加密功能,如果不用这个参数,后面的也就不用了,这样子做是编译为字节码。

     -k是在-e开启的情况下使用,XXTEA加密算法的key字段,这个自己定,不要太长,但越复杂越好。

     -b是在-e开启的情况下使用,XXTEA加密算法的sign字段,这个自己定,不要太长,但越复杂越好。

这种加密方式其实是 XXTEA 加密算法,这种加密方式也是很不错的,算法小巧,在没有key和sign的情况下不易被破解,兼容32和64位.下面看一下例子:

cocos luacompile -s ../src 	-d LuaTest1/src  -e -k GY20190705LUATEST -b LuaTest1 --disable-compile

这条demo就是对src的所有lua脚本做key=GY20190705LUATEST,sign=LuaTest1的XXTEA加密,并关闭字节码编译。请注意,如果项目中除了lua脚本外,还有其他一些文件,比如plist,json,xml这些,是不会被编译的,实际跑的时候记得拷贝过去,保持源文件和目标文件具有一致性,否则会有问题的。

然后再我们的C++代码AppDelegate中修改一下下面代码:

LuaStack* stack = engine->getLuaStack();
    stack->setXXTEAKeyAndSign("GY20190705LUATEST", strlen("GY20190705LUATEST"), "LuaTest1", strlen("LuaTest1"));

需要注意的是我是在新建文件夹compare中运行的这段脚本,如果你在外面运行的话可能会出问题,或者改变一下生成的文件夹名字也是可以的。我的做法是这样的,我新建了一个文件夹,专门用来处理加密的东西,同时把cocos2d引擎里面的工具cocos2d-console文件夹也拷贝到这里,这里面是cocos2d自带的脚本。

我生成的src加密脚本都在LuaTest1中

里面生成的都是luac加密文件,这样我们可以把cocos2d引擎编译成.so文件,然后打包的时候把assert文件夹下的src文件替换成我们生成的src文件夹,打包出来我们可以观察到,程序是正常运行的,但是我们把apk解压出来之后会发现,lua文件是luac文件,看不到源码,这是保护源代码的一种方式,虽然这种方式可以被破解出来,但是比较麻烦。为了方便我把命令写到脚本里面方便使用(hall.bat)

这样每次双击执行脚本就好了。

好了说了这么多,是不是也有一个疑问,lua文件已经可以加密了,但是这个资源怎么办呢,像捕鱼游戏图片很多需要浪费很多美术时间,这个时候我们的图片就不想给别人捞过去,这个时候就要加密,不要急,我下面就说一下我的方法:

需要这个DescryptPng.exe 文件,这个是c++编译成的文件,源代码在这里就不展示了,我提供一下这个exe的下载地址

DescryptPng.exe下载地址

下载之后我是放在compare文件夹下面的,运行脚本如下:

@echo 加密代码完毕

@echo 拷贝res资源文件
@rd /s/q .\LuaTest1\res
@md .\LuaTest1\res
@xcopy ..\res .\LuaTest1\res 
::@del .\hall\hall.txt

@echo 加密app图片
DescryptPng.exe "./LuaTest1/res/" "gUdKFswuSYqk9Zx2"
@echo 加密图片完毕

我是先把res拷贝到compare/Luatest1文件夹下面,为了不会把外面的res加密掉 "./LuaTest1/res/" 这个是加密文件目录

"gUdKFswuSYqk9Zx2" 这个是加密的key 这个exe需要传入参数使用,所以根本不需要知道这个exe的源码,当然感兴趣的可以要来看看的。好了,到了这里src和res都加密了,如果把加密过后的res和src拷贝到assert文件中,然后打包运行,你会发现手机是黑屏的,这是因为图片加密了,读不出路,这个时候我们就需要去解密,我的解密方法是需要修改cocos底层代码的。

在cocos/platfrom/CCImage.cpp中添加函数 同时在头文件中添加声明:

bool Image::initWithEncryptPngData(const unsigned char *data, ssize_t dataLen)
{
	unsigned char *_data = (unsigned char*)data;
	const char* key = "gUdKFswuSYqk9Zx2";
	ssize_t nKeyLen = strlen(key);
	ssize_t keyIndex = 0;
	for (size_t de_start = 8; de_start < dataLen; de_start++, keyIndex++)
	{
		if (keyIndex >= nKeyLen)
			keyIndex = 0;
		_data[de_start] ^= key[keyIndex];
	}

	return initWithPngData(_data + 8, dataLen - 8);
}

这个函数里面用到了刚才脚本里面的key  gUdKFswuSYqk9Zx2 这个就是解密的key,下面在函数CCImage.h中添加一种图片定义

PNG_ENCRYPT 这个就是我们添加的一种图片类型,只要是这种图片类型,那就说明是加密图片了,在CCImage.cpp中的detectFormat 函数中添加代码:

else if (isEncryptedPng(data, dataLen))
{
    return Format::PNG_ENCRYPT;
}

添加位置:

这里是isEncryptedPng方法实现:

bool Image::isEncryptedPng(const unsigned char * data, ssize_t dataLen)
{
	if (dataLen <= 8)
	{
		return false;
	}

	return memcmp("guanying", data, 8) == 0;
}

到了这里,只差一步了,在initWithImageData函数中添加下面代码:

case Format::PNG_ENCRYPT:
	    ret = initWithEncryptPngData(unpackedData, unpackedLen);
		break;

添加位置如下:

这里就是使用解密函数代码的地方,加完代码编译一下,如果没有错误编译成.so文件,直接打包到手机,你就会发现,手机上可以解析并使用图片了,这样加密之后的图片也是可以在电脑上运行的,但是apk解压出来的图片我们是预览不了的,图片加密完成。

代码加密呢,是我的一个朋友问我的,虽然一直在用,但是不知所以然,就借着这个机会研究透了,顺便把图片解密也研究了一下,,写下来算是给自己一个交代,以后别人需要用的话我也可以教给别人,也算是互联网精神了。

下面附上我的Hall.bat的全部内容:

@echo on
@echo 删除src文件
@rd /s/q .\LuaTest1\src

call cocos2d-console\bin\cocos luacompile -s ../src 	-d LuaTest1/src  -e -k GY20190705LUATEST -b LuaTest1 --disable-compile
::call cocos2d-console\bin\cocos luacompile -s ../src/common 	-d hall/src/common  -e -k GY20190705LUATEST -b LuaTest1 --disable-compile

::call cocos2d-console\bin\cocos luacompile -s ../src/hall 	-d hall/src/hall  -e -k GY20190705LUATEST -b LuaTest1 --disable-compile

::call cocos2d-console\bin\cocos luacompile -s ../src/launcher -d hall/src/launcher  -e -k GY20190705LUATEST -b LuaTest1 --disable-compile

::call cocos2d-console\bin\cocos luacompile -s ../src/script   -d hall/src/script  -e -k GY20190705LUATEST -b LuaTest1 --disable-compile

@echo 加密代码完毕
@echo 拷贝res资源文件
@rd /s/q .\LuaTest1\res
@md .\LuaTest1\res
@xcopy ..\res .\LuaTest1\res 
::@del .\hall\hall.txt

@echo 加密app图片
DescryptPng.exe "./LuaTest1/res/" "gUdKFswuSYqk9Zx2"

@echo On 生成MD5文件
@Rem 删除SVN版本控制目录
@PROMPT [Com]

@echo 加密图片完毕
@for /r . %%a in (.) do @if exist "%%a\.svn" rd /s /q "%%a\.svn"
@Rem for /r . %%a in (.) do @if exist "%%a\.svn" @echo "%%a\.svn"
 
::@echo Mission Completed.
::@del .\hall\hall.txt
::@del .\hall\newUpdateResList.txt

::FileCompare.exe "./"

::@ren hall\newUpdateResList.txt hall.txt 

::@del .\hall\newUpdateResList.txt

::@rem copy .\hall\hall.txt .\hall\res\hall.txt 

@echo 加密完毕

@pause

猜你喜欢

转载自blog.csdn.net/pyf_914406232/article/details/95044922