skynet lua 代码加密

原文 2015-08-13 01:19:34 发表于 CSDN,这里对以前写的文章做下收录。

要实现 lua 代码加密,可以利用 luac 编译代码文件成二进制实现加密。


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 为例

luaservice = root.."bin/?.lua;"
lualoader = root.."bin/loader.lua"
snax = root.."bin/?.lua"

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

lua 执行代码时也要相应做修改,否则无法执行。

这样就可以了,但是要注意了,不能同时修改以上两处内容,编译和执行要分开处理,否则无法编译 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 的实现,继续做分享。

发表评论

邮箱地址不会被公开。 必填项已用*标注