lua 代码加密方案

require 实现

  • require函数在实现上是依次调用package.searchers(lua51中是package.loaders)中的加载函数,成功后返回。在loadlib.c文件中有四个加载函数的实现,分别为searcher_preload, searcher_Lua, searcher_C, searcher_Croot。
  • searcher_preload是从读取LUA_REGISTRYINDEX的_PRELOAD字段,已经require过的文件会写入到该表中
  • searcher_Lua是根据文件名查找package.path中的所有路径的lua文件,存在文件则返回
  • searcher_C是搜索package.cpath中的所有路径下的库文件
  • searcher_Croot是对require(“a.b.c”)的情况,读取c库,然后查找函数名为lua_a_b_c的lua_CFunction函数
static void findloader (lua_State *L, const char *name) {
  int i;
  luaL_Buffer msg;  /* to build error message */
  luaL_buffinit(L, &msg);
  lua_getfield(L, lua_upvalueindex(1), "searchers");  /* will be at index 3 */
  if (!lua_istable(L, 3))
    luaL_error(L, LUA_QL("package.searchers") " must be a table");
  /*  iterate over available searchers to find a loader */
  for (i = 1; ; i++) {
    lua_rawgeti(L, 3, i);  /* get a searcher */
    if (lua_isnil(L, -1)) {  /* no more searchers? */
      lua_pop(L, 1);  /* remove nil */
      luaL_pushresult(&msg);  /* create error message */
      luaL_error(L, "module " LUA_QS " not found:%s",
                    name, lua_tostring(L, -1));
    }
    lua_pushstring(L, name);
    lua_call(L, 1, 2);  /* call it */
    if (lua_isfunction(L, -2))  /* did it find a loader? */
      return;  /* module loader found */
    else if (lua_isstring(L, -2)) {  /* searcher returned error message? */
      lua_pop(L, 1);  /* remove extra return */
      luaL_addvalue(&msg);  /* concatenate error message */
    }
    else
      lua_pop(L, 2);  /* remove both returns */
  }
}
  • 现在要实现在require时能读取加密文件,有两种办法,一种是直接修改源代码,即修改第二个加载函数,重新实现其中读取文件内容的函数,第二种办法是在lua中修改package.searchers表,在加载器的第一和第二种之间添加一个加载器函数,该加载器模拟searcher_Lua函数,搜索path路径,然后逐个匹配文件,然后读取文件内容,解密,然后调用load加载并返回(c中为luaL_loadbufferx),这里在加载时最好传入文件名作为来源参数,方便在调试信息中定位.
  • 加密方案可使用类似xxtea轻量级的加密算法
  • 在对lua文件进行加密打包时,可以在文件头写入指定的签名内容,以方便在解密前预先判断是否为有效的加密文件

修改lua源代码方案

  • 在searcher_Lua中最终是调用lua_load(L, getF, &lf, lua_tostring(L, -1), mode)加载源文件,该函数的第二个参数getF是一个lua_Reader函数,所以这里可以重写该函数以实现解密,也可以向外部暴露一个接口用来将自定义的文件读取函数作为参数传给lua_load。下面是原版的getF实现
static const char *getF (lua_State *L, void *ud, size_t *size) {
  LoadF *lf = (LoadF *)ud;
  (void)L;  /* not used */
  if (lf->n > 0) {  /* are there pre-read characters to be read? */
    *size = lf->n;  /* return them (chars already in buffer) */
    lf->n = 0;  /* no more pre-read characters */
  }
  else {  /* read a block from file */
    /* ‘fread‘ can return > 0 *and* set the EOF flag. If next call to
       ‘getF‘ called ‘fread‘, it might still wait for user input.
       The next check avoids this problem. */
    if (feof(lf->f)) return NULL;
    *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);  /* read block */
  }
  return lf->buff;
}

外部修改加载器方案

  • 直接修改package.searchers表,向其中添加加载器,c版实现如下
void addLuaSearcher(lua_CFunction func)
{
    if (!func) return;

    // stack content after the invoking of the function
    // get loader table
    lua_getglobal(m_state, "package");          /* L: package */
    lua_getfield(m_state, -1, "loaders");       /* L: package, loaders */
    // insert loader into index 2
    lua_pushcfunction(m_state, func);           /* L: package, loaders, func */
    for (int i = lua_objlen(m_state, -2) + 1; i > 2; --i)
    {
        lua_rawgeti(m_state, -2, i - 1);        /* L: package, loaders, func, function */
        // we call lua_rawgeti, so the loader table now is at -3
        lua_rawseti(m_state, -3, i);            /* L: package, loaders, func */
    }
    lua_rawseti(m_state, -2, 2);                /* L: package, loaders */
    // set loaders into package
    lua_setfield(m_state, -2, "loaders");       /* L: package */
    lua_pop(m_state, 1);
}
  • 加载器函数实现根据传入的文件名,逐个匹配的package.path中的内容,存在文件后,然后读取文件内容,解密,最后再将解出的内容调用load加载并返回(c中为luaL_loadbufferx),实现可以参照lua源码中的searcher_Lua实现
时间: 2024-10-03 11:05:13

lua 代码加密方案的相关文章

cocos2dx lua 代码加密

代码加密使用luajit加密 具体文件路径就是: ....\frameworks\cocos2d-x\external\lua\luajit\src\src 加密的工具windows bat批处理: 代码如下: @echo off if exist out rd /s /q out mkdir out :input cls set input=: set /p input= ÍÏÈëÒª±àÒëµÄluaÎļþ¼Ð£º set "input=%input:"=%" if &

Lua代码加密,防止代码反编译

加密目的: 在游戏开发中,脚本作为一种资源文件,就像图片视频一样,被引擎所引用.如果不对脚本进行加密,不怀好意的人轻松解压出脚本文件,给你瞬间复制一个游戏出来.在程序发布前一般会对脚本进行加密,防止代码泄漏. 加密工具: Virbox Protector DS Protector 优点: 便捷,一键加壳,无需编写代码. 安全,混淆.虚拟化.碎片代码.反黑.定制SDK等最新加密安全技术. 快速,5分钟完成整个程序加壳,专注软件开发. 灵活,云锁.软锁.硬件锁三种许可形式,可满足联网或离线场景,云和

skynet项目lua代码简单加密

最近在看skynet的代码,总体感觉跟 erlang很像,理念都是基于Actor模型,即万物皆Actor,Actor之间通过发送消息进行通信.(这里说的"万物"倾向于表示有能动作用,有独立行为的个体.) 不同的是,skynet使用 c 和 lua实现,这两个语言相较erlang比较流行.skynet的Actor是指skynet服务,skynet服务类似erlang进程,调度方式也有点接近,skynet启动时会初始化多个调度线程,用于同时处理多个服务,每个服务都有一定的调度次数约束,挂起

[自动化-脚本]002.cocos2dx-lua lua代码windows加密批处理

在开发软件的时候,我们都会在项目上线时候对代码进行加密,用来防止被不法分子盗走牟利.不同的语言有不同的加密方式,比较出名的有加壳,代码混淆等.在Lua开发cocos2dx的时候,框架会有提供加密的脚本.下面我说说加密windows的步骤 1.要知道要加密的源码的存放路径,并指定备份路径 2.把代码拷贝到备份路径 3.对所有的脚本进行去bom处理 4.用php命令compile_scripts.php进行加密处理. 根据以上的四点,我们下面贴出UTF8 去bom的代码和加密的整体代码 1.UTF-

关于cocos2dx手游lua文件加密的解决方案

很多使用cocos2dx+lua做游戏的同学,都会想到一个问题,我的游戏一旦发布,怎样才能保证的我脚本代码不被破解,不泄露代码.虽然这和开源.共享的原则不合,但是代码也是coder的劳动成果,理应得到保护.特别是商业游戏更是如此,不希望被别人破解掉源码并且进行修改. 今天的话题就是如何实现lua脚本文件的加密和解密. 我在网络上查过,解决方案http://www.ijiami.cn/appprotect_mobile_games然后我经过考虑之后,总结出两种解决方案,供大家参考. 1.轻量级的解

关于cocos2dx手游lua文件加密的解决方式

非常多使用cocos2dx+lua做游戏的同学.都会想到一个问题,我的游戏一旦公布,如何才干保证的我脚本代码不被破解.不泄露代码.尽管这和开源.共享的原则不合.可是代码也是coder的劳动成果,理应得到保护. 特别是商业游戏更是如此,不希望被别人破解掉源代码而且进行改动. 今天的话题就是怎样实现lua脚本文件的加密和解密. 我在网络上查过,都没有成熟的解决方式.然后我经过考虑之后,总结出两种解决方式,供大家參考. 1.轻量级的解决方式.APK打包之前,用工具把全部的lua文件加密,详细是将lua

iOS代码加密常用加密方式

在今天的面试中,被问到了iOS是采用什么进行加密解密操作的,我的回答是这样的:AES,MD5,Base 64,然后是对这几种加密算法进行了一下简单的介绍和概述和几种算法之间的不同点和优缺点.然而,收到的回答是:这些都不是iOS的加密!我顿时就无语了,这不就是iOS加密所用到的方法么?然后向面试官请教了一下:MD5是一种摘要....什么叫加密呢?加密是客户端对数据加密和服务器端采用秘钥对数据进行解密处理,为了数据的安全考虑.要说加密应该是RSA.幸亏之前有了解过RSA,只是了解的不是很彻底和清楚.

cocos2dx android运行Luac编译后的lua代码

运行环境 win7 64 cocos2d-2.1rc0-x-2.1.2 lua 5.1 通常我们编写好的lua代码都是明文形式,谁都可以查看修改,为了防止自己的劳动成果不被别人轻易的盗取,可以使用luac(lua库中自带)对其进行加密,转换为二进制文件.这样lua代码就无法直接查看,但是这里会有一个问题:在windows下能够很好的运行,在android上就会黑屏,提示错误: [LUA ERROR] binary string: unexpected end in precompiled chu

把代码加密成乱码?不如让代码隐身吧!

先声明,娱乐向,至于有没有实用价值就不知道了...轻喷哈. 今天在网上乱逛的时候看到了陈浩大牛的这篇博客:http://coolshell.cn/articles/1142.html 感觉里面说的WhiteSpace语言很有意思.维基百科: http://zh.wikipedia.org/wiki/Whitespace 一般的编程语言都会忽略空白字符,而WhiteSpace却只识别空白字符,优点竟然是“不能把代码打印带走”... 虽然不知道有没有人真的用这个语言做项目开发,但是这给了我们一个思路