为什么L-> l_G-> _defaultmeta.value.gc总是NULL? [英] Why is L->l_G->_defaultmeta.value.gc always NULL?

查看:141
本文介绍了为什么L-> l_G-> _defaultmeta.value.gc总是NULL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在试图破解游戏的Lua实现,以扩展游戏模块的内置方法。

为了这样做,我尝试劫持一个指向有效的 lua_State 结构体的指针,并用它注册新的库。



目标游戏的几个地方/阶段拦截程序并从中窃取 lua_State 。我的第一次尝试是在 base_open()最后的 luaL_openlib()中调用。这是我第一次得到这个空指针异常:

 异常抛出:读取访问冲突。 

L-> l_G-> _defaultmeta.value.gc为nullptr。

从您可以看到的评论中,



我知道我试过的游戏在这里入侵使用 Lua 5.0的稍微不同的版本 , em> ,但是它可能会改变垃圾收集工作方式或其他方式吗?因为有...... ..




还有一件事要记住:



游戏已经将Lua编译进去了。我创建的DLL具有它自己的Lua 5.0.1编译。当然,有一个机会,游戏开发者当时决定不仅仅是轻松地改变Lua,而是改变它很多 。我总是假设所有开发人员都在删除一些默认库并添加了一些其他内置函数,如 LOG() WARN() 等等。如果他们在Lua的核心中更改代码会很奇怪 - 但我告诉你,有人对Lua有一个想法可能会认为这是我得到的异常的解释。

解决方案

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

lua_TObject包含一个类型标签( tt)以及价值联盟。该联合中最大的东西通常是8字节双精度(如果是64位,则是8字节指针,但这是32位精度)。其他一般都是4个字节。观察窗口中的大部分内容看起来非常有效,但lua_Objects外观粗略。 _defaultmeta紧跟在另一个lua_TObject之后,所以如果lua_TObject的大小不同,你的代码和游戏代码将不同意这个成员的位置。 tde for _defaultmeta应该是5(LUA_TTABLE),但你的看起来像它可能是一个指针。此外,top,base和_registry的tt字段表示其他类型的指针类型值,但gc字段表示您的代码看到的是小整数而不是指针。这些可能是相邻lua_tobjects的字段。最重要的是,top和base没有相同的16字节对齐方式,这些应该是指向同一个lua_tobject数组的指针。



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



如果你有权访问编译的Lua游戏使用的大块,你也可以看看这些块的头部信息。这将包含一些信息,可能有助于匹配您的Lua配置,包括sizeof(lua_Number)。



(但我认为有可能将双打变为浮动)

它也可以帮助你将调试检查添加到你自己的Lua构建中,至少在开始时可能会在任何有趣的业务中提前警告你。它看起来像Lua 5.0允许lua_assert和api_check为此目的而定义。



祝你好运!


I am currently trying to hack the Lua implementation of a game in order to extend the built-in methods for game modders.

In order to do so, I try to hijack a the pointer to a valid lua_State struct and register new libraries with it.

I have now tried several places / stages of the target game to intercept the program and steal lua_State from it. My first try was callin in luaL_openlib() at the very end of base_open(). This was the first time I got this null-pointer exception:

Exception thrown: read access violation.

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

From the comments you can see, that Egor Sktiptunoff suggested to me moving the entry point of my hack into a user-level function. Since I know, that one of the first functions getting called is dofile(), I stole the lua_State struct from there and passed it to my DLL.

What you see here is the actual code from my injected DLL which I tried to execute at the end of base_open() and dofile() (user-level):

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"
}

Below you can find the screenshot of a debug session and the location where the exception gets thrown. The lua_State object is the one that I stole and was passed to e.g. dofile. How can it be that L->l_G->_defaultmeta.value.gc is NULL at this point in time? Is there anything I can do here or is there any explanation for this?

I know that the game which I try to hack here uses a "slightly different version of Lua 5.0", but could it be that they changed the way how garbage collection works or something? Because there is ..


One more thing to keep in mind:

The game has Lua compiled into it. The DLL I created has its own compilation of Lua 5.0.1. There is of course a chance, that the game developers back then decided to not just "sligtly" change Lua, but instead change it a lot. I am always just assuming that all the developers did was removing some default libraries and added some other built-in functions like LOG(), WARN(), etc. It would be strange if they changed code in Lua's core - but I tell you that just so somebody who has an idea about Lua might consider this as an explanation for the exception I am getting here.

解决方案

It really looks like your sizeof(lua_TObject) doesn't match what the game's Lua is using. A common reason for this to be different is using floats (or ints) as numbers instead of the default double. I haven't personally made this change in Lua 5.0, but it looks like it can be done by defining LUA_NUMBER as float (or int). With int/float the size should be 8, but with double it is 16 (not 12 because the double needs to be aligned).

lua_TObject consists of a type tag (tt) along with a value union. The largest thing in that union is usually the 8-byte double (or an 8-byte pointer if 64-bit, but this is 32-bit). Everything else is typically 4 bytes. Most of the stuff in your watch window looks pretty valid, but the lua_Objects look sketchy. And _defaultmeta comes directly after another lua_TObject, so if the size of lua_TObject is different, your code and the game code will disagree about the location of this member. tt for _defaultmeta should be 5 (LUA_TTABLE), but yours looks like it is probably a pointer. Also, the tt fields for top, base, and _registry indicate other types that will have a pointer type value, but the gc field indicates your code is seeing small integers instead of pointers. These are probably tt fields of adjacent lua_TObjects. On top of all that, top and base don't have the same 16-byte alignment, and these are supposed to be pointers into the same lua_TObject array.

If you continue having trouble, try examining the lua_State object you get from the game before you have modified it, and compare it to the lua_State you see in a cleanly initialized lua_State you have made yourself. Obviously, pointer addresses may differ, and the game may be setting up some contents you are not, but some inconsistencies may still jump out.

If you have access to compiled Lua chunks that the game uses, you could also look at the header information of these chunks. This will contain some information that could be helpful in matching your Lua configuration including sizeof(lua_Number).

(But I think there is some chance that changing doubles to floats could be sufficient.)

It may also help you to add debugging checks to your own Lua build that may warn you sooner in the case of any funny business, at least initially. It looks like Lua 5.0 allows for both lua_assert and api_check to be #defined for such purposes.

Good luck!

这篇关于为什么L-> l_G-> _defaultmeta.value.gc总是NULL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆