【问题标题】:How do I restore/call an original function after it's redefined?重新定义后如何恢复/调用原始函数?
【发布时间】:2019-10-06 04:57:56
【问题描述】:

我使用的是LuaJIT 2.1,当我需要隐藏源代码时,我先将其混淆以防止脚本被反编译,然后再编译。

我们知道我们可以通过重新定义来挂钩 LUA 中的任何函数:

local __load = load
load = function(data, ...)
    -- some stuff, e.g. you can unpack the data var to a file
    return __load(data, ...)
end

如果有人将我的脚本与他们的脚本一起加入(例如上面),他们可以真正挂钩我脚本中的任何内置和全局函数,以及访问我自己定义的全局变量和函数(这就是为什么我总是将所有函数和变量定义为本地函数)。

所以,问题是我如何调用它们的原始函数或至少将它们恢复到它们的原始块。如果这是可能的话。


可能没有帮助的答案:

  • _G['function_name'] 包含新函数的地址。
  • pcall(string.dump, function_name)检查函数是件好事,但它也可以被钩住。

如果你听不懂我说的话:

  • “加入脚本”是指使用loadloadstring 将它们相互组合,之后这些脚本可以相互访问。

【问题讨论】:

    标签: lua luajit


    【解决方案1】:

    Lua 沙盒基于编译块是你的编译块的假设。如果有人能够挂钩 Lua 脚本加载过程并在编译器看到它们之前将任意内容附加到您的 Lua 脚本,那么您就无法将它们沙箱化。这是您在安全过程中的失败点,所以这就是您必须防御的。这需要 Lua 本身边界之外的工具。

    但是请注意,如果您正在加载 预编译 块,用户(仅限于常规 Lua 脚本)无法在该块的末尾添加内容。至少,不是在常规 Lua 5.1 中; LuaJIT 的加载器可能不同。当然,如果他们已经交换了 load 函数,那么他们也可以编辑字节码本身,所以如果他们已经走到了那一步,你还是不走运。


    关于 Lua 沙盒的事情是它不能在脚本中完成。无论您的脚本使用什么环境(全局等)都是那个环境。这是由加载和执行脚本的代码管理的。如果它没有明确地做任何事情来将一个脚本所做的全局更改与另一个脚本进行隔离,那么您的脚本对此无能为力。

    【讨论】:

    • 所以这意味着我们不能在不重建 lua51.dll 的情况下保护我们的脚本免受外部干预?从字面上看,任何人都可以闯入您编译的脚本,因为load 函数可以加载已编译的脚本(字节码),无论它是 lua 还是 luajit 编译的脚本。其实很简单
    • @user70960:你确定吗?我编写了一个测试脚本,它尝试获取两个预编译的块并将它们都推入load,并且只执行第一个块。我什至将两个预编译的字符串拼接在一起并将它们推入loadstring,它仍然只执行第一个。现在,我使用基线 Lua 5.1 而不是 LuaJIT,所以这可能是不同的。但这会是 LuaJIT 的奇怪行为。
    • @user70960: Here is my test script 如果你想自己尝试一下。
    • @user70960:这些脚本没有“加入”,也没有“相互访问”。这只是一个脚本在另一个之前执行,根本没有尝试沙盒。您的问题表明 load itself 已被覆盖,因此您失去了对沙箱的控制权。但你没有。您展示的示例甚至没有尝试对这些脚本进行沙盒处理。那么,您是否可以控制编译/执行这些脚本的代码?
    • @user70960:首先,停止发布 Youtube 视频;压缩太大了,看不到任何东西,即使不是,我也无法复制/粘贴任何东西。其次,如果您无法控制实际加载和执行脚本的程序,那么您就无法控制任何事情。您不能从您尝试构建的沙箱中对 Lua 进行沙箱处理。您的脚本受加载和执行它们的环境的支配。总是。
    猜你喜欢
    • 2015-09-05
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多