LuaJ的Lua字节码混淆

我在使用LuaJ生成Lua字节码时遇到了问题。在指令计数和常量计数之间出现了问题。似乎少了一个字节。我使用的是LuaJ 2.0.3版本。以下是一个十六进制转储,展示了我的问题: hexdump

该字节码是使用以下代码生成的:

string.dump(function() return "athin" end)

常量计数显示了250个常量,但实际上只应该有一个。如果在常量计数和指令列表之间多一个字节,它将完美地工作:

常量计数将为1,第一个常量的类型为4(字符串),字符串的长度为6,包括末尾的空字符。

为什么不能正常工作?为什么会少一个字节?我该如何解决这个问题?

点赞
用户3266171
用户3266171

注意: 我最初将此帖子发布在 CC 论坛 这里

实际上,您缺少一个 0x00 字节。作为“指令”,您有 00 00 00 01 01 00 00 1E 00 00 1E 00

查看 Lua 5.1 VM 指令入门指南,即可进行翻译:

LOADK 0 0 -- 将索引 0 上的常量加载到寄存器 0 中。
RETURN 0 2 -- 返回从寄存器 0 开始的 1 个值。
MOVE 120 0 -- 将寄存器 120 的值复制到寄存器 0 中。

最后一个是毫无意义的。为什么字节码生成器会插入这样一个永远不会被执行的荒谬指令?

如果您在最后一个指令中添加一个 0x00 字节,则其变为 00 00 00 01 01 00 00 1E 00 00 00 1E

这翻译为:

LOADK 0 0 -- 将索引 0 上的常量加载到寄存器 0 中。
RETURN 0 2 -- 返回从寄存器 0 开始的 1 个值。
RETURN 0 0 -- 返回从寄存器 0 到栈顶的所有值。

如果您阅读了 PDF,则会发现即使 Lua 源代码中已经有显式返回语句,字节码生成器也总是在字节码末尾添加一个返回语句。因此,这个反汇编是有意义的。

无论如何,如果您在那里添加了额外的 0x00 字节,则它会将其余的字节码移位,使其有意义,正如您所说的那样。只是缺少的 0x00 字节不在“指令”和“常量数”之间,而是作为指令的一部分。

现在,我不知道这对您有什么用处,因为输出直接来自 CC(或LuaJ),但这是问题所在。

注意: 修改 ChunkSpy 以接受大端块后,它会在您发布的字节码中出错,但如果按您或我建议的方式修改字节码,则可以正常工作。

2014-06-07 12:23:08