skynet项目lua代码简单加密

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

不同的是,skynet使用 c 和 lua实现,这两个语言相较erlang比较流行。skynet的Actor是指skynet服务,skynet服务类似erlang进程,调度方式也有点接近,skynet启动时会初始化多个调度线程,用于同时处理多个服务,每个服务都有一定的调度次数约束(处理消息条数),挂起或达到约束就失去调度权。不过skynet服务的调度不是轮转,而是消息驱动方式(先来消息先调度)。实现上,每个服务都是一个lua state,也就是一个lua虚拟机,效果等同沙箱,实现隔离。另外,lua state本身没有多线程支持的,skynet实现上在一个线程运行多个lua state实例。

好了,切入今天的主题吧,skynet项目lua代码加密。文章利用lua编译成二进制实现加密,方法比较简单。

lua编译

lua代码可以被编译二进制文件,就是lua可以同时支持源代码加载和二进制加载两种方式。
但是,lua编译成二进制有一点使用限制,lua二进制支持跨平台,跨版本,但必须在相同字长的机器上。就是说,32位lua编译的二进制不能在64位下使用。另外,虽然官方表示可跨版本,但也声明了跨版本可能存在不兼容的情况,具体情况没有说明。
另一点,lua代码编译成二进制,不意味着执行更快,这个过程只是预编译,将代码编译成字节码(bytecodes)。因为lua源代码执行前也要生成字节码,所以二进制方式在一定程度上提高了代码加载的速度。


lua编译器

luac [ options ] [ filenames ]
options 说明:
options 
说明
-l
生成lua编译后字节码的可视化数据,这对于学习lua虚拟机很有帮助
-o file
编译lua代码,输出文件为file。默认生成 luac.out
-s
写入输出文件时去掉调试信息。可以减少输出文件的大小,但错误信息就比较简单,例如,少了行号和局部变量名
-v
显示版本信息


编译skynet项目的lua脚本

skynet没有提供工具来生成,所以这里简单写个脚本演示下。目前skynet没有支持luajit
#!/bin/bash

LUAC=./3rd/lua/luac
mkdir -p bin

Luas=`find . -name "*.lua"`
for file in $Luas
do
    filename = `basename $file`
    $LUAC -o bin/$filename $file
done
脚本执行完后,编译后的代码就会输出到 bin 目录。为了代码能够被执行到,还需要修改配置文件,所有的lua文件都要从bin路径查找。
以 examples/config 为例
root = "./"
thread = 8
logger = nil
logpath = "."
harbor = 1
address = "127.0.0.1:2526"
master = "127.0.0.1:2013"
start = "main" -- main script
bootstrap = "snlua bootstrap" -- The service for bootstrap
standalone = "0.0.0.0:2013"
luaservice = root.."bin/?.lua;"
lualoader = root.."bin/loader.lua"
snax = root.."bin/?.lua"
-- snax_interface_g = "snax_g"
cpath = root.."cservice/?.so"
-- daemon = "./skynet.pid"


lua代码加密的另一种方式

前面介绍了把lua代码编译成二进制达到加密目的,这已经足够了。如果想进一步加密代码,可以使用下面的方法。
luac编译时,通过以下函数输出到文件,这里以异或加密为例说明。
// luac.c

static int writer(lua_State* L, const void* p, size_t size, void* u)
{
 int ret = !0;
 size_t i =0;
 char* pp = (char *)malloc(sizeof(char*)*size); 
 UNUSED(L);
 memcpy(pp, p, size);
 for(;i<size;i++) pp[i] ^=250;
 ret = (fwrite((void*)pp,size,1,(FILE*)u)!=1) && (size!=0);
 free(pp);
 return ret;
}
lua执行代码也要相应做修改,否则无法执行。
//lauxlib.c

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 */
  }
  do{size_t i=0; for(;i<*size;) lf->buff[i++] ^= 250;}while(0);
  return lf->buff;
}
这样就可以了,但是要注意了,不能同时修改以上两处内容,编译和执行要分开处理,否则无法编译lua代码。(skynet版本不同,代码可以不同,仅参考)


luajit编译

按照skynet的计划,lua有可能换上luajit。luajit也支持二进制编译,lua代码加密方式类似。
luajit -b filename newfile
luajit -b test.lua test.out                           # Save bytecode to test.out
luajit -bs test.lua test.out                         # As above, Strip debug info (default).
luajit -bg test.lua test.out                        # Keep debug info
luajit -be "print('hello world')" test.out  # Save cmdline script
luajit -bl test.lua                                       # List to stdout
luajit -bl test.lua test.txt                           # List to test.txt
luajit -ble "print('hello world')"              # List cmdline script

最后语

最后回顾下,文章利用lua编译成二进制实现加密,编译成字节码,可直接被lua加载,比较实用。比较之下,改编译器代码不是很适用,这里只是提供可能的思路。
好了,今天就到这里。再研究下skynet的实现,继续做分享。

参考:http://blog.csdn.net/mycwq/article/details/47406337
版权声明:本文为“没有开花的树”原创文章,未经博主允许不得转载。

相关文章推荐

skynet 控制台管理使用技巧

skynet 自带了一个控制台服务,可以很方便获取和调试 skynet 运行数据,而且可以热更新代码,所以,弄明白skynet控制台管理可以让你更好地使用skynet,甚至改进这个控制台服务,以满足不...

lua 代码加密方案

lua 代码加密方案,直接修改源码和外部修改加载器
  • jncpp
  • jncpp
  • 2015-03-14 16:13
  • 3147

Lua文件加密

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

Unity3D AssetBundle 资源加载-IOS

今天分享下,在IOS上如何打包Assetbundle和加载Assetbundle,我们知道有很多类似的文章,但是还是想简单和大家一起学习一下,希望对一些刚刚学习unity3d的同学有帮助。    好...

cocos2d-x-lua工程的lua脚本加密

转自:http://www.cnblogs.com/mrblue/archive/2013/06/06/3122543.html

轻量级加密lua

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

skynet lua 代码静态分析

skynet是一款为多人在线游戏设计的服务端框架,使用c+lua开发。skynet这套框架的一个优点是,通常只需要写lua代码,很少用到c做开发,一定程度上提高了开发效率。而skynet文档相对较少,...

Vs调用luacheck静态检查

Vs调用luacheck静态检查(金庆的专栏 2017.3)1. 安装luacheck    1. 下载 luacheck-0.19.0    2. 解压复制到 d:/tools/luacheck-0...

Erlang获取当前时间

可以用erlang:now()和os:timestamp()来获取当前时间,返回的是形如{MegaSecs, Secs, MicroSecs}这样的元组,如{1396,707464,903000}。

网络游戏开发之安全对抗

游戏才刚上线没多久,就遭遇了众多游戏工作室一波接一波的外挂洗礼。游戏工作室很喜欢新游戏,因为新游戏没有太多对抗外挂的手段和技术,漏洞也较多,而且新游戏会不断烧钱导量,游戏工作室也借机找到了大量的客户。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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