当前位置 : 主页 > 网络编程 > lua >

lua – 为什么L-> l_G – > _ defaultmeta.value.gc总是为NULL?

来源:互联网 收集:自由互联 发布时间:2021-06-23
我目前正试图破解游戏的Lua实现,以扩展游戏模块的内置方法. 为了做到这一点,我试图劫持指向有效的lua_State结构的指针并用它注册新的库. 我现在已经尝试了目标游戏的几个位置/阶段来
我目前正试图破解游戏的Lua实现,以扩展游戏模块的内置方法.

为了做到这一点,我试图劫持指向有效的lua_State结构的指针并用它注册新的库.

我现在已经尝试了目标游戏的几个位置/阶段来拦截程序并从中窃取lua_State.我的第一次尝试是在base_open()末尾的luaL_openlib()中调用.这是我第一次得到这个空指针异常:

Exception thrown: read access violation.

L->l_G->_defaultmeta.value.gc was nullptr.

从你可以看到的评论中,Egor Sktiptunoff建议我将我的黑客入口点移动到用户级函数中.因为我知道,被调用的第一个函数之一是dofile(),我从那里偷走了lua_State结构并将其传递给我的DLL.

你在这里看到的是我注入的DLL中的实际代码,我尝试在base_open()和dofile()(用户级)结束时执行:

EXTERN_DLL_EXPORT void initialize(lua_State *L)
{
    if (initialized == true) {
        return;
    }

    initialized = true;

    lua_pushvalue(L, LUA_GLOBALSINDEX);          // Works
    luaL_openlib(L, "ext", extension_funcs, 0);  // Crashes with "L->l_G->_defaultmeta.value.gc was nullptr"
}

您可以在下面找到调试会话的屏幕截图以及抛出异常的位置. lua_State对象是我偷走并传递给的对象,例如dofile处理. L-> l_G-> _defaultmeta.value.gc在这个时间点如何才为NULL?我有什么可以做的,或者有什么解释吗?

我知道我试图在这里破解的游戏使用的是“slightly different version of Lua 5.0”,但可能是因为他们改变了垃圾收集的工作方式或其他方式?因为有……

还有一点要记住:

该游戏已将Lua编入其中.我创建的DLL有自己的Lua 5.0.1编译.当然,游戏开发者当然有机会决定不再“轻易”改变Lua,而是改变它.我总是假设所有开发人员都删除了一些默认库并添加了一些其他内置函数,如LOG(),WARN()等.如果他们更改Lua核心中的代码会很奇怪 – 但我告诉你那些对Lua有所了解的人可能会认为这是对我所遇到的异常的解释.

它看起来像你的sizeof(lua_TObject)与游戏的Lua使用的不匹配.这种情况不同的常见原因是使用浮点数(或整数)作为数字而不是默认的双精度数.我没有亲自在Lua 5.0中做过这个改变,但看起来可以通过将LUA_NUMBER定义为float(或int)来完成.对于int / float,大小应该是8,但是加倍是16(不是12因为double需要对齐).

lua_TObject由一个类型标记(tt)和一个值联合组成.该联合中最大的东西通常是8字节的双精度(如果是64位,则为8字节指针,但这是32位).其他一切通常是4个字节.监视窗口中的大多数内容看起来非常有效,但lua_Objects看起来很粗略.并且_defaultmeta直接来自另一个lua_TObject,因此如果lua_TObject的大小不同,您的代码和游戏代码将不同意该成员的位置. tt for _defaultmeta应该是5(LUA_TTABLE),但你的看起来可能是一个指针.此外,top,base和_registry的tt字段表示其他具有指针类型值的类型,但gc字段表示您的代码看到的是小整数而不是指针.这些可能是相邻lua_TObjects的tt字段.最重要的是,top和base没有相同的16字节对齐,这些应该是指向同一个lua_TObject数组的指针.

如果你继续遇到麻烦,尝试在修改之前检查你从游戏中获得的lua_State对象,并将它与你在自​​己创建的干净初始化的lua_State中看到的lua_State进行比较.显然,指针地址可能不同,游戏可能会设置一些你不是的内容,但是一些不一致可能仍会跳出来.

如果您可以访问游戏使用的已编译的Lua块,您还可以查看这些块的头信息.这将包含一些有助于匹配Lua配置的信息,包括sizeof(lua_Number).

(但我认为有可能将双打换成浮点数就足够了.)

它还可以帮助您将调试检查添加到您自己的Lua构建中,这可能会在任何有趣的业务情况下提前警告您,至少最初是这样.看起来Lua 5.0允许lua_assert和api_check为此目的而#defined.

祝你好运!

网友评论