我目前正试图破解游戏的Lua实现,以扩展游戏模式的内置方法。
为了做到这一点,我尝试劫持指向有效lua_State
结构的指针,并用它注册新的库。
我现在尝试了目标游戏的几个位置/阶段来拦截程序并从中窃取lua_State
。我的第一次尝试是在luaL_openlib()
结束时base_open()
中的callin。这是我第一次得到这个空指针异常:
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
怎么可能是LOG()
?我有什么可以做的,或者有什么解释吗?
我知道我尝试在这里破解的游戏使用了“ slightly different version of Lua 5.0 ”,但可能是因为他们改变了垃圾收集的方式工作还是什么?因为有...
要记住的另一件事:
游戏已将Lua编入其中。我创建的DLL有自己的Lua 5.0.1 编译。当然游戏开发者当然有机会决定不仅仅是“ sligtly ”改变Lua,而是改变它很多。我总是假设所有的开发人员都删除了一些默认库并添加了一些其他内置函数,如WARN()
,Sub FindAndReplace()
Dim FoundCell As Range
With Columns("A:A")
Set FoundCell = .Find(What:="old", After:=.Cells(1), _
LookIn:=-4163, LookAt:=1, SearchOrder:=1, SearchDirection:=1, MatchCase:=True, MatchByte:=False, SearchFormat:=False)
If FoundCell Is Nothing Then
MsgBox ("Item not in the sheet...")
Exit Sub
Else
.Replace What:="old", Replacement:="new", LookAt:=1, _
SearchOrder:=1, MatchCase:=True, SearchFormat:=False, _
ReplaceFormat:=False
End If
End With
End Sub
等。如果他们更改了Lua核心中的代码,那会很奇怪 - 但是我告诉你,那些对Lua有所了解的人可能会认为这是我在这里得到的例外的解释。
答案 0 :(得分:3)
看起来你的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字段。最重要的是,顶部和底部没有相同的16字节对齐,这些应该是指向同一个lua_TObject数组的指针。
如果你仍然遇到问题,请尝试在修改之前检查游戏中获得的lua_State对象,并将其与您在自己创建的干净初始化的lua_State中看到的lua_State进行比较。显然,指针地址可能不同,游戏可能会设置一些你不是的内容,但是一些不一致可能仍会跳出来。
如果您可以访问游戏使用的已编译的Lua块,您还可以查看这些块的头信息。这将包含一些有助于匹配Lua配置的信息,包括sizeof(lua_Number)。
(但我认为将双打更改为浮点数有可能就足够了。)
它还可以帮助您将调试检查添加到您自己的Lua版本中,这可能会在任何有趣的业务中提前警告您,至少最初是这样。看起来Lua 5.0允许lua_assert和api_check为此目的而#defined。
祝你好运!答案 1 :(得分:0)
如果您只想添加一些全局函数,只需设置一个名为luaL_reg
的合适myfuncs
结构,然后调用
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_openlib(L, NULL, myfuncs, 0); /* open lib into global table */
在您自己的C代码中执行此操作。
无需更改lbaselib.c
的来源。