如何在使用 luac 编译代码时保留调试信息

我在文件“orgin.lua”中编写了以下代码

if test==nil then
    print(aa["bb"]["cc"])  -- to produce a crash
end
print(1120)

当它崩溃时,会生成以下信息:

lua: origin.lua:3: attempt to index global 'aa' (a nil value)

为了防止反编译并确保代码安全,我使用以下命令转换我的代码:

luac -o -s test.lua origin.lua

我知道参数-s是剥离调试信息,那么当崩溃时就不会显示行号:

lua: ?:0: attempt to index global 'aa' (a nil value)

但是在使用 luac 编译加密代码时如何保留调试信息?是否有解决方案?

点赞
用户4117435
用户4117435

Lua 中没有内置的方法来实现这个,但有一些解决办法。

如果你仅仅需要行号,那么一个选项是在代码块中保留行号。行号对于逆向工程并不是很有用(目前 unluac 并未使用它们),因此它不应影响安全性。Lua 没有为此提供选项,但在剥离时保留行号很容易进行修改。从 ldump.c:

n = (D->strip) ? 0 : f->sizelineinfo;

可以改为

n = f->sizelineinfo;

(免责声明:未经测试)

一个更复杂的选项是修改 Lua 运行时程序,输出虚拟机程序计数器而不是行号,同时输出描述代码块当前函数位置的信息(例如,顶层、第一个函数、第二个函数嵌套在第三个函数中等)。然后开发人员可以在未剥离的代码块中查找行号。(这里是一个 参考 ,描述了有人在 lua-l 上使用该方法 -- 但没有提供源代码。)

请注意,防止反编译并不是真正的安全措施。它可能对抗一些随意攻击有所帮助,但阅读 Lua 字节码并不困难。

2018-02-11 06:43:44
用户2420301
用户2420301
`luac` 不会加密输出。它只是将你的 Lua 源代码编译成字节码。代码不会被加密,也不会运行更快,只是加载时间更短,因为不需要编译步骤。

如果你想加密你的代码,我建议使用 AES-256 加密字节码,然后在将其交给 Lua 状态之前在内存中解码。这样,字节码在磁盘上被加密,但是在内存中被解密。

开销很低。我们使用这种技术已经很多年了。`
2018-02-11 09:04:15