如何为 Lua 的虚拟机/编译器重新编译已编译的字节码列表?

作为我的软件工程课程的一个独特的研究项目,我正在尝试修改一款名为 Fun Run 2 的旧移动游戏的代码。

该应用是使用 Corona SDK 制作的,因此是用 Lua 编写的。因此,一旦我拿到了 APK 并解压缩它,我就需要解压缩 resource.car(Corona ARchive)以访问 Lua 文件。于是,我做到了,该存档中的所有文件都是预编译的.lu文件。

为了修改 Lua 代码,我尝试的第一件事是使用 unluac/luadec 将.lu文件反编译为可读的、可修改的、可编译的源代码。我成功地反编译、修改和重新编译了它们,但是当它确实在游戏中执行修改的.lu文件时,它会因为试图索引一个空值而崩溃。我发现造成这个问题的原因是有一种称为upvalue的东西,当从编译后的Lua文件中剥离调试信息时,它们是不可能检索到的,因此尝试反编译和重新编译.lu文件是行不通的。

因此,我接下来的方法是使用 luac -l 的方法,它为 Lua 的虚拟机创建了一个已编译字节码的列表。

luac -l lua.gameLogic.powerUpChance.lu 的结果大致如下:

...
main <?:0,0> (11 instructions, 44 bytes at 025D7D80)
0+ params, 3 slots, 0 upvalues, 0 locals, 4 constants, 2 functions
    1   [-] NEWTABLE    0 0 0
    2   [-] GETGLOBAL   1 -1    ; require
    3   [-] LOADK       2 -2    ; "composer"
    4   [-] CALL        1 2 2
    5   [-] CLOSURE     2 0 ; 025D8280
    6   [-] MOVE        0 1
    7   [-] SETTABLE    0 -3 2  ; "selectRandomPowerUp" -
...

有了这个指令列表,我知道需要修改的内容和在哪里修改它,因此我进行了修改。这就带来了我的问题——我如何将修改后的字节码列表编译回已编译的.lu文件中?这个可能吗?修改已编译的Lua文件的这种方法是浪费我的时间吗?

点赞
用户4984564
用户4984564

没有工具(至少我不知道有)可以将字节码的字符串表示编译回正确的 Lua 字节码,因为这不是用来编辑的,而是用来检查你的 Lua 代码编译成什么样子并且可能进行优化的。

一个更好的解决方案是使用将字节码反编译成 Lua 代码的工具。使用哪个工具取决于所使用的 Lua 版本,但对于从 5.1 到 5.3 的任何版本,有一个名为 LuaDec 的工具,我没有亲自试过,但应该能完成工作。一旦你反编译了源代码,进行所有必要的修改并像处理任何 Lua 文件一样使用 luac 再次编译就行了。

希望这有所帮助 :)

2019-02-07 09:29:40
用户6834680
用户6834680

似乎你正在使用的反编译器无法正确反编译 for 循环。

以下代码片段:

if A1_3 == #A3_5 and A2_4 > 2 then
   for _FORV_9_ = 1, #A3_5 do
   end
   if _FOR_ then
      L5_7 = 11
   end
end

应该像这样:

如果 A1_3 == #A3_5 且 A2_4 > 2,则
   local R6 = true
   for k = 1, #A3_5 do
      if not A3_5[k].mainPlayer then
         if A3_5[k].x < A0_2.x + 1200 then
            R6 = false
         end
      end
   end
   if R6 then
      L5_7 = 11
   end
end
2019-02-07 17:31:23