原文 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 的实现,继续做分享。