我试图通过引入新的内置方法和功能来破解游戏(尽管不是为了作弊),以便使用套接字与游戏进行通信。这是我要完成的一个小的“伪代码”示例:

在Lua代码中,我正在调用my_hack()并传递当前游戏状态:



GameState = {}

-- Game state object to be passed on
function GameState:new()
  -- Data
end

local gameState = GameState:new()
-- Collect game state data and pass it to 'my_hack' ..
my_hack(gameState)


并在my_hack内将对象送走:现在,最大的问题是如何在游戏中引入my_hack()

我认为,所有内置函数都必须保留在某种查找表中。由于所有的Lua代码都得到了解释,因此像import之类的功能必须是静态可用的,对吗?如果正确,那么应该足够“找出”该代码在哪里,以便将我的代码走私到游戏中,从而允许我在Lua脚本中调用my_hack()

那里应该有两个选择:第一个是所构建的Lua嵌入在可执行文件中,并且是完全静态的,第二个是从DLL动态加载所有Lua代码。

任何对我应该在哪里以及如何继续寻找内置函数的线索一无所知的人都会遇到这个问题。我已经尝试使用Cheat Engine进行一些操作,但是我并不太成功。我可以作弊^^,但这不是我想要的。


这就是我当前的“进度”: >我在可执行文件的数据部分找到了一些要尝试的提示。例如IDA给我

int my_hack(lua_State * l)
{
   void* gameState= lua_topointer(l, 1);

   // Send the game state:
   socket->send_data(gameState);

   return 0;
}


现在,我知道这里的这些字符串(loadfile,dofile等)实际上是修改器的内置函数的名称可以在Lua中使用-一种脚本语言来更改游戏中的内容。

我试图找出正在访问该地址以进行读取的时间。为此,我正在使用Cheat Engine,此时我想强调一点,我并不是在这里作弊,而是要引入新的内置功能,以便在改装时具有更大的灵活性。

但是,我在IDA中看到的地址似乎不是实际的虚拟地址。如果我用Cheat Engine来看这个地址,那只是读出内存,我什么也没得到。

所以问题是我是否能够找到正确的虚拟地址,例如dofile以便从我的RAM中读取该信息。

最后我希望看到的是从哪里访问这些方法,然后在以后的步骤中可能会找到dofile的实际代码居住。最后,我想将我的代码走私到正确的位置并引入一个新功能my_hack,以控制程序。

#1 楼

一种方法是:使用IDA在目标二进制文件中本地化lua_gettop(应该经常调用)。您可以通过下载Lua源代码来获取它,并在目标二进制文件中查找错误消息。通过查看包含错误消息的lua函数的XRef,您应该能够逐渐重建Lua运行时。
钩住lua_gettop,并在第一个参数中检索lua_State引用:





lua_State * hLua = NULL;

int __cdecl lua_gettop_hook (lua_State *self) {
    int (__cdecl *hooked) (lua_State *) =
        (typeof(hooked)) get_original_function (lua_gettop_hook);
    hLua = self;
    return hooked (self);
}



一旦调用了lua_gettop钩子,请在游戏过程中加载您自己的luaXX.dll版本(使用LoadLibrary )。确保加载与游戏中相同的lua库版本! -例如lua51.dll。





HMODULE lua51 = LoadLibrary(str_dup_printf("%s/luajit/lua51.dll", luaPath));



调用所需的函数使用被盗的lua_State参考,例如luaL_loadfile:
使用GetProcAdress加载luaL_loadfile,并将其命名为:



/>
这样,您就可以使用游戏的当前Lua上下文注入自己的Lua代码。

评论


这听起来很合理,实际上离我目前正在努力的目标并不遥远。我下载了Lua代码,发现有一个列表base_funcs具有名称/地址对,例如{“ loadfile”,luaB_loadfile}等。似乎这些是Lua的内置函数。我发现此数组被传递给luaL_openlib(),该文件在lbaselib.c文件的base_open()中被调用。对我来说,好像luaL_openlib()确实注册了这些功能。因此,如果我没记错的话,我应该可以做这样的事情:

– Stefan Falk
16 Dec 5'在11:05

在可执行文件中找到base_open()并将jmp注入到一个位置,以便在我注入加载my-lua-extension.dll的代码后进一步调用类似initialize_my_lua_extension(lua_State * L)的代码。由于我有luaL_openlib的起始地址,因此我可以在dll中调用此函数,从而注册新的方法/函数。我不必替换整个Lua实现或替换它们,而只需注册其他方法。我在这里要问的是,调用luaL_openlib是否足够以及解释器是否能够解析我的新方法。

– Stefan Falk
16 Dec 5'在11:08