【第22期】观点:IT 行业加班,到底有没有价值?

lua源文件加密

原创 2016年08月30日 17:21:28

在游戏开发中,脚本作为一种资源文件,就像图片视频一样,被引擎所引用,使用脚本做游戏的好处就在于可以在线patch更新,特别对于苹果App Store审核期很长的情况。如果不对脚本进行加密,不怀好意的人松松解压出脚本文件,给你瞬间复制一个游戏出来。

自己写的小游戏没有必要用太复杂的加密方式,最简单的一种就是利用cocos提供的一种加密方式  luacompile加密


1.  打开terminal   cd 到cocos2d-x引擎bin 目录           ---我的目录   /Users/apple/Documents/cocos2d-x-3.8.1/tools/cocos2d-console/bin


2.运行    cocos luacompile -s /Users/apple/Desktop/Project/.../src/app -d /Users/apple/Documents/123 -e -k key -b sign --disable-compile

-s :需要加密的文件跟目录

-d :加密后的文件路径 

-k 和-b:加密的密钥

--disable-compile 标示简单用XXTEA加密  对于简单的小游戏加密这足够了也避免了支持64bit的问题


3.替换加密后的文件 ------------打包上线


注: key 和sign

在app delegate文件里设置key和sign

 LuaStack* stack = engine->getLuaStack();

    stack->setXXTEAKeyAndSign("key........", strlen("key........."), "sign.......", strlen("sign......"));


这一句的第二和第四个参数都是前一个参数的长度,并不是固定值,可以自己指定
最后需要注意的是: 编译发布程序的时候要记得把源代码文件夹从项目中移除(不是删除,只是不包含进项目里),不然一切都白费了 。 
到此整个过程结束,我们的代码已经被很好的保护起来了。



还有一种方式比较复杂,前面的已经能加密成功了后面这种方式就没再测试了,有兴趣可以测试一下


异或加密解密

最简单的一种加密方式,虽然简单,但是也比较实用。但是防破解方面确实一般,如果你有其他严格的仿破解需求,可以将这部分加密算法换成你自己的复杂算法,不过保证解密效率。下面是采用C++简单实现的对文件进行加密之后保存到原文件中(注意对原始未加密文件进行备份)

 代码如下 复制代码
#include "stdafx.h"
#include<iostream>
#include<ctime>
#include<fstream>
using namespace std;
void Makecode(char *pstr,int *pkey);
void Cutecode(char *pstr,int *pkey);
void encode_file(char *f);
int _tmain(int argc, _TCHAR* argv[])
{
encode_file("e:/src/ResultScene.lua");
/*
encode_file("e:/src/ReadyScene.lua");
encode_file("e:/src/GameScene.lua");
encode_file("e:/src/PutHeadScene.lua");
encode_file("e:/src/TutorialsScene.lua");
encode_file("e:/src/WordsCategoryScene.lua");
encode_file("e:/src/common/DictHelper.lua");
encode_file("e:/src/common/LJ.lua");
encode_file("e:/src/common/DQueue.lua");
encode_file("e:/src/common/UIHelper.lua");
*/
    int c;
    cin>>c;    
    return 0;
}
void encode_file(char *f)
{
FILE *fp = NULL;
fopen_s(&fp, f,"rb");
fseek(fp,0,SEEK_END); //定位到文件末 
int nFileLen = ftell(fp); //文件长度
cout << "file len = " << nFileLen << endl;
fseek(fp, 0, SEEK_SET);
char *fileContent = NULL;
fileContent = (char *) malloc ((nFileLen + 1) * sizeof(char));//增加一位
memset(fileContent, 0, nFileLen + 1);
fileContent[nFileLen] = '';//最后一位置为结束位
fread_s(fileContent,nFileLen, 1, nFileLen, fp);
//fread(buf,nFileLen, 1, fp);
//cout<<"解密前:"<<fileContent<<endl;
fclose(fp);
cout<<"文件:"<<f<<endl;
cout<<"解密前文件大小:"<<strlen(fileContent)<<endl;
    int key[]={1, 2, 6, 1, 2, 6};//加密字符
    char *p=fileContent;
cout<<"====="<<endl;
    Makecode(fileContent,key);//加密
    //cout<<"加密后:"<<p<<endl; 
cout<<"加密后文件大小:"<<strlen(fileContent)<<endl;
FILE *stream = NULL;
fopen_s(&stream, f,"wb");
if (stream == NULL) /* open file TEST.$$$ */
    {
        fprintf(stderr, "Cannot open output file.
");
    }
else {
fwrite(p, nFileLen, 1, stream); /* 写的struct文件*/
fclose(stream); /*关闭文件*/
}
cout<<"====="<<endl;
    Cutecode(fileContent,key);//解密
    //cout<<"解密后:"<<fileContent<<endl;
}
//单个字符异或运算
char MakecodeChar(char c,int key){
    return c=c^key;
}
//单个字符解密
char CutcodeChar(char c,int key){
    return c^key;
}
//加密
void Makecode(char *pstr,int *pkey){
    int len=strlen(pstr);//获取长度
    for(int i=0;i<len;i++)
        *(pstr+i)=MakecodeChar(*(pstr+i),pkey[i%5]);
}
//解密
void Cutecode(char *pstr,int *pkey){
    int len=strlen(pstr);
    for(int i=0;i<len;i++)
        *(pstr+i)=CutcodeChar(*(pstr+i),pkey[i%5]);
}

2.修改Cocos2d-x引擎中加载lua脚本文件(或者js文件)的入口,在加载的时候对其进行解密。可能不同版本引擎有不同的入口文件,在Cocos2d-x3.0中,对应的是文件Cocos2dxLuaLoader.cpp文件中的int cocos2dx_lua_loader(lua_State *L)方法,对其进行修改成如下:

 代码如下 复制代码
#include "Cocos2dxLuaLoader.h"
#include <string>
#include <algorithm>
#include<iostream>
using namespace cocos2d;
extern "C"
{
    //单个字符异或运算
    char MakecodeChar(char c,int key){
        return c=c^key;
    }
    //单个字符解密
    char CutcodeChar(char c,int key){
        return c^key;
    }
    //加密
    void Makecode(char *pstr,int *pkey){
        int len=strlen(pstr);//获取长度
        for(int i=0;i<len;i++)
            *(pstr+i)=MakecodeChar(*(pstr+i),pkey[i%5]);
    }
    //解密
    void Cutecode(char *pstr,int *pkey){
        int len=strlen(pstr);
        for(int i=0;i<len;i++)
            *(pstr+i)=CutcodeChar(*(pstr+i),pkey[i%5]);
    }
    int cocos2dx_lua_loader(lua_State *L)
    {
        std::string filename(luaL_checkstring(L, 1));
        size_t pos = filename.rfind(".lua");
        if (pos != std::string::npos)
        {
            filename = filename.substr(0, pos);
        }
         
        pos = filename.find_first_of(".");
        while (pos != std::string::npos)
        {
            filename.replace(pos, 1, "/");
            pos = filename.find_first_of(".");
        }
        filename.append(".lua");
         
        Data data = FileUtils::getInstance()->getDataFromFile(filename);
         
        if (!data.isNull())
        {
         
            //====code decode start==================================
            log("===encode filename:%s===", filename.c_str());
            //如果filename == 'main.lua',则解密
            char *fileContent = (char*)data.getBytes();
            int key[]={1, 2, 6, 1, 2, 6};//加密字符
            char *fileContentDecoded = NULL; 
            if (strcmp(filename.c_str(),"ReadyScene.lua")==0 || 
            strcmp(filename.c_str(),"GameScene.lua")==0 || 
            strcmp(filename.c_str(),"PutHeadScene.lua")==0 || 
            strcmp(filename.c_str(),"TutorialsScene.lua")==0 || 
            strcmp(filename.c_str(),"WordsCategoryScene.lua")==0 || 
            strcmp(filename.c_str(),"DictHelper.lua")==0 || 
            strcmp(filename.c_str(),"LJ.lua")==0 || 
            strcmp(filename.c_str(),"ResultScene.lua")==0 || 
            strcmp(filename.c_str(),"DQueue.lua")==0 || 
            strcmp(filename.c_str(),"UIHelper.lua")==0 ) {
            if (data.getSize() < strlen(fileContent)) {
            fileContentDecoded = (char *) malloc ((data.getSize() + 1) * sizeof(char));//增加一位
            memset(fileContentDecoded, 0, data.getSize() + 1);
            fileContentDecoded[data.getSize()] = '';//最后一位置为结束位
            strncpy(fileContentDecoded,fileContent,data.getSize());
            fileContent = NULL;
            }
            else {
            fileContentDecoded = fileContent;
            }
            Cutecode(fileContentDecoded,key);//解密
            }
            else {
            fileContentDecoded = fileContent;
            }
            //====code decode end==================================
 
            if (luaL_loadbuffer(L, fileContentDecoded, data.getSize(), filename.c_str()) != 0)
            {
                luaL_error(L, "error loading module %s from file %s :
    %s",
                    lua_tostring(L, 1), filename.c_str(), lua_tostring(L, -1));
            }
        }
        else
        {
            log("can not get file data of %s", filename.c_str());
        }
        return 1;
    }
}
 


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Lua文件加密

项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚本编译为字节码(bytecode)从而实现加密,试了一下,确实可行。 下面是使用原生的lua解释器编译字节码: ...

6月30日苹果中国区所有游戏需要广电总局审批才可上架的通知,从此就呵呵哒了

之前5月份广电局一封邮件通知让整个业界惊魂未定,种种谣言和辟谣纷纷四起,今天,6月30日,苹果终于没有能抗衡住广电总局的压力,在开发者后台贴出这样的醒目通知: 致中国地区游戏开发人员: 根据2...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

Lua代码加密

Lua代码加密 NOV 22ND, 2013 | COMMENTS 开发者为了防止代码泄漏,在发布前一般会对脚本进行加密,加密方式有多种, 比如常见的AES, XXTEA .. 等等,...

Lua 脚本的加密

原文链接:http://www.cocoachina.com/bbs/read.php?tid=205802 项目要求对lua脚本进行加密,查了一下相关的资料 ,得知lua本身可以使用luac将脚...

cocos2dx 3.4 lua加密 和 解密

1.在自己项目的根目录下按住Shift键, 右击鼠标, 点击“在此处打开命令窗口” 然后输入 cocos luacompile -s src/ -d out/ -e -k...

轻量级加密lua

首先是压缩lua文件,代码如下:      [cpp] view plaincopy int write_file_content(const ch...

cocos2dx 3.xLua脚本加密解密

使用LUA脚本开发游戏有着诸多的优势,动态更新,不需要考虑内存和数据类型等等。但是LUA脚本的安全性问题却似的许多开发者非常苦恼。 我这两天因为LUA脚本加密的问题苦恼了好久,经过了两天的努力,...

skynet项目lua代码简单加密

最近在看skynet的代码,总体感觉跟 erlang很像,理念都是基于Actor模型,即万物皆Actor,Actor之间通过发送消息进行通信。(这里说的“万物”倾向于表示有能动作用,有独立行为的个体。...

cocos2d luajit对Lua脚本编译加密的批处理工具

在项目中要对lua代码进行加密。在论坛上看到一个方法使用cocos2d引擎所包含的luajit对其进行编译加密。         地址是:cocos2d-x使用Luajit将Lua脚本编译为bytec...

lua脚本基础语法

Lua基础语法 1.          注册C语言函数 lua语言的工作原理实例:   int foo(lua_State *L)//在C语言中定义函数foo {  int  n = lua_ton...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)