4

I am trying to hack a game (not for cheating though) by introducing new built-in methods and functions in order to communicate with the game using sockets. Here is a small "pseudo code" example of what I want to accomplish:

Inside the Lua code I am calling my_hack() and pass the current game state:

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)

and inside my_hack the object is getting sent away:

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

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

   return 0;
}

Now, the big question is how to introduce my_hack() to the game?

I assume, that all built in functions must be kept in some sort of lookup table. Since all Lua code is getting interpreted, functions like import etc. will have to be statically available, right? If that is correct, then it should be "enough" to find out where this code is residing in order to smuggle my code into the game that would allow me to call my_hack() in a Lua script.

There should be two options: The first is that the Lua built is embedded inside the executable and is completely static and the second is that all Lua code gets loaded dynamically from a DLL.

This question goes out to anybody who has a slightest clue about where and how I should keep looking for the built in functions. I've tried a few things with Cheat Engine but I wasn't too successful. I was able to cheat a bit ^^ but that's not what I'm looking out for.


This is what my current "progress" looks like:

I found some hints I'm trying to go after in the data section of the executable. For example IDA is giving me

.rdata:00D44210                 dd offset aLoadfile     ; "loadfile"
.rdata:00D44214                 dd offset sub_90ECE0
.rdata:00D44218                 dd offset aDofile       ; "dofile"
.rdata:00D4421C                 dd offset sub_90ED20
.rdata:00D44220                 dd offset aLoadstring   ; "loadstring"
.rdata:00D44224                 dd offset sub_90EC80

Now, I know that these strings here (loadfile, dofile, etc.) are actually the names of built-in functions that modders can use in Lua - a script language in order to change stuff in the game.

I am trying to find out at which point this address is being accessed for reading. For that I am using Cheat Engine and at this point I would like to stress that I am not trying to cheat here but to introduce new built-in functions in order to have more flexibility when it comes to modding.

However, the addresses which I see in IDA do not seem to be the actual virtual addresses. If I look at this address with Cheat Engine, which is just reading out the memory, I'm getting nothing.

So the question is if I will be able to find the correct virtual address of e.g. dofile in order to read that out from my RAM.

What I hope to see in the end is from where these methods are getting accessed and in a much later step maybe find out where the actual code of dofile resides. At the end I want to smuggle my code into the right place and introduce a new function my_hack in order to get control of the program.

2

One way of doing this :

  • Localize lua_gettop in your target binary with IDA (which should be called very frequently). You can get it by downloading Lua sources, and look for error messages in your target binary. You should be able to reconstruct little by little the Lua runtime by looking at XRefs of lua functions containing error messages.

  • Hook lua_gettop, and retrieve the lua_State reference in the first argument :

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);
}
  • Once your lua_gettop hook have been called, load your own version of luaXX.dll inside the game process (using LoadLibrary). Make sure you load the same lua library version than in the game! - for instance, lua51.dll.

HMODULE lua51 = LoadLibrary(str_dup_printf("%s/luajit/lua51.dll", luaPath));
  • Call the function you want using the stolen lua_State reference, for instance luaL_loadfile :

  • Load luaL_loadfile using GetProcAdress, and call it :

LOADFILEFN _luaL_loadfile = (typeof(_luaL_loadfile)) GetProcAddress (lua51, "luaL_loadfile"); 

// Load custom script "script.lua"
if (_luaL_loadfile (hLua, str_dup_printf("%s/script.lua", scriptPath))) {
    MessageBox (NULL, "Cannot load script.lua", "ERROR", 0);
}

By doing so, you'll be able to inject your own Lua code using the current Lua context of the game.

  • That sounds reasonable and in fact it's not so far away from what I'm currently trying to do. I downloaded the Lua code and found that there is a list base_funcs which has name/address pairs e.g. {"loadfile", luaB_loadfile} etc. It seems these are the built-in functions of Lua. I found that this array is getting passed to luaL_openlib() which is getting called in base_open() in file lbaselib.c. To me it looks like as if luaL_openlib() does register these functions. So if I am not mistaken I should be able to do something like this: – displayname Dec 5 '16 at 11:05
  • Locate base_open() in the executable and inject a jmp to a location wher I inject code that loads my-lua-extension.dll and further calls something like initialize_my_lua_extension(lua_State *L). Since I have the starting address of luaL_openlib I simply could call this function within my dll and therefore register new methods/functions. I would not have to replace the whole Lua implementations or replace them but would only register additional methods. The question I'd have here whether calling luaL_openlib is enough and if the interpreter will then be able to parse my new methods. – displayname Dec 5 '16 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.