2

我在解析使用 luaJ 生成的 lua 字节码时遇到问题。在指令计数常量计数之间出现了问题。好像少了一个字节。我正在使用 LuaJ 2.0.3。


这是一个十六进制转储,显示了我 十六进制转储

的意思:字节码是使用生成的

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



常量计数显示 250 个常量,但应该只有一个。如果在常量计数和指令列表之间多出 1 个字节,它将完美运行:

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


为什么这不起作用?为什么缺少一个字节?我该怎么做才能解决这个问题?

4

1 回答 1

2

注意:我首先在此处的 CC 论坛上发布了此内容。

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

查看Lua 5.1 VM Instructions 的简单介绍,翻译为:

LOADK 0 0 -- Load constant at index 0 into register number 0.
RETURN 0 2 -- Return 1 value, starting at register number 0.
MOVE 120 0 -- Copy the value of register number 120 into register number 0.

最后一个没有任何意义。为什么字节码生成器会插入这样一条永远不会执行的荒谬指令?

如果您在最后一条指令中添加一个 0x00 字节,则它读作00 00 00 01 01 00 00 1E 00 00 00 1E.

这转化为:

LOADK 0 0 -- Load constant at index 0 into register number 0.
RETURN 0 2 -- Return 1 value, starting at register number 0.
RETURN 0 0 -- Return all values from register number 0 to the top of the stack.

如果你阅读 PDF,你会发现字节码生成器总是在字节码的末尾添加一个 return 语句,即使 Lua 源代码中已经有一个显式的 return 语句。因此,这种拆卸是有道理的。

无论如何,如果你在那里添加一个额外的 0x00 字节,它会将其余的字节码转移过来,所以它是有意义的,就像你说的那样。只是缺少的 0x00 字节不在“指令”和“常量数”之间,它是指令的一部分。

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

注意:在修改 ChunkSpy 以接受 big-endian 块后,它在您发布它时在字节码上出错,但如果按照您建议的方式修改,或者我建议的方式修改字节码,它可以正常工作。

于 2014-06-07T12:23:08.993 回答