xiangtingsl 发表于 2022-5-11 08:22

Lua的编译和反编译

背景

无论是unity项目还是unreal的项目,我都使用了lua!!既然用了lua那么打包的时候肯定是离不开Lua的编译和反编译了!
Lua的编译


[*]Luac
[*]Luajit
以上两种应该是比较常用的了,当然,你可以自定义加密和解密的算法!
Luac

lua的安装在这里就不累述了!
测试使用的lua文件 TestLua.lua
local AAClass = {}
function AAClass:TestFunction(value1)
    print(value1)
end

function AAClass:TestAdd(a, b)
    return a+b
end

local str = "Test!!!"
local obj = AAClass
obj:TestFunction(str)

local numA=10
local numB=50
local res = obj:TestAdd(numA, numB)
print(res)
return使用指令lua ./TestLua.lua测试一下代码是否正确!
PS Desktop\testLua> lua .\TestLua.lua
Test!!!
60Luac是对lua进行编译为luac字节码!
luac -o TestLua.bytes .\TestLua.lua



编译成功!
使用编译后的字节运行看看!
PS Desktop\testLua> lua .\TestLua.bytes
Test!!!
60完美!
Luajit

目前unity项目使用的是Luajit所以,这个方案也要看看!
Luajit的环境可以自己下载编译,自行安排,我比较懒,就直接冲unity里把luajit直接考来用就行了!
注意:
unknown luaJIT command or jit.* modules not installed如果出现上文的报错,把 luajit\src\src\jit 文件放到 luajit.exe 同级目录的 lua 文件夹下。
.
├── lua
│   └── jit
│       ├── bc.lua
│       ├── bcsave.lua
│       ├── dis_arm.lua
│       ├── dis_mips.lua
│       ├── dis_mipsel.lua
│       ├── dis_ppc.lua
│       ├── dis_x64.lua
│       ├── dis_x86.lua
│       ├── dump.lua
│       ├── p.lua
│       ├── v.lua
│       ├── vmdef.lua
│       └── zone.lua
├── lua51.dll
├── lua51.exp
├── lua51.lib
└── luajit.exe还是上文的TestLua.lua
直接luajit运行一下!
PS Desktop\testLua> .\luajit64\luajit64.exe .\TestLua.lua
Test!!!
60妥了!开始编译一下
.\luajit64\luajit64.exe -b -g .\TestLua.lua TestLua.jitbytes



运行一下字节
PS Desktop\testLua> .\luajit64\luajit64.exe .\TestLua.jitbytes
Test!!!
60简单比较一下两种编译的结果!



其他更加详细的ua程序逆向之Luajit文件格式
Lua的反编译

Luac

目前对于luac的反编译普遍使用的是luadec这个工具:
https://github.com/viruscamp/luadec
git clone https://github.com/viruscamp/luadec
cd luadec
git submodule update --init lua-5.1然后进入vcproj-5.1使用vs打开编译就可以了!
试一下反编译!
PS Desktop\testLua> G:\other_workspace\luadec\vcproj-5.1\Debug\bin\luadec.exe .\TestLua.bytes > .\TestLua_Decode.lua得到以下的代码!
-- Decompiled using luadec 2.2 rev: 895d923 for Lua 5.1 from https://github.com/viruscamp/luadec
-- Command line: .\TestLua.bytes

-- params : ...
-- function num : 0
local AAClass = {}
AAClass.TestFunction = function(self, value1)
-- function num : 0_0
print(value1)
end

AAClass.TestAdd = function(self, a, b)
-- function num : 0_1
return a + b
end

local str = "Test!!!"
local obj = AAClass
obj:TestFunction(str)
local numA = 10
local numB = 50
local res = obj:TestAdd(numA, numB)
print(res)
returnLuajit

google一下,你会看到很多luajit decompile的内容,但是不少都需要复杂的操作,而已还不是那么直观 (也有可能是我技术不到位,有知道的大佬可以link评论我学习一下)。
我借助了别人的一个工具:https://github.com/zzwlpx/ljd项目中使用的luajit2.1.0-beta3,工具说明是luajit2.1.0-beta2,但是我对比一下luajit源码中的opcode,没有差异!
由于ljd源码目前仅支持32位的字节码反编译,如果要支持64位,需要改ljd的python代码,暂时我没有时间,写这个文章只是因为我想看看打包后lua文件有没有正确,工程里是有32位的字节文件的!
PS Desktop\testLua> .\luajit32\luajit32.exe -bg .\TestLua.lua TestLua.jitbytes 这里先保留debug信息吧!
将编译好的TestLua.jitbytes移动到ljd目录下执行指令py main.py .\TestLua.jitbytes >.\jitDecode.lua
local AAClass = {
    TestFunction = function (self, value1)
      print(value1)

      return
    end,
    TestAdd = function (self, a, b)
      return a + b
    end
}
local str = "Test!!!"
local obj = AAClass

obj.TestFunction(obj, str)

local numA = 10
local numB = 50
local res = obj.TestAdd(obj, numA, numB)

print(res)

return上面的就是decompile出来的,可读性还是杠杠的! 如果是不带-g的呢?
({
    TestFunction = function (slot0, slot1)
      print(slot1)

      return
    end,
    TestAdd = function (slot0, slot1, slot2)
      return slot1 + slot2
    end
})["TestFunction"](slot2, slot1)
print(({
    TestFunction = function (slot0, slot1)
      print(slot1)

      return
    end,
    TestAdd = function (slot0, slot1, slot2)
      return slot1 + slot2
    end
})["TestAdd"](slot2, slot3, 50))

return也勉强能接受,毕竟信息少了很多!
最后再放一下我参考的文件!
LuaJIT反编译总结
Lua程序逆向之Luac文件格式分析
页: [1]
查看完整版本: Lua的编译和反编译