Lua 5.1 discover function signature - lua

I am trying to redocument the mod library for a game called 'harvest massive encounter'
Their documentation that I was able to find:
http://www.oxeyegames.com/wiki/index.php/Harvest_Library
Redocumenting everything they have documented isn't an issue, I've also found a way to discover the hooks they did not document. But I am unable to figure out a way to discover their undocumented functions.
For example: harvest.defineActionButton seems like something that I would really want to discover to make cool actions on buildings available. Where defineUpgradeButton is also a button on a building, but also replaces it.
Sadly, this button is not documented but it does exist. If I do harvest.print(type(harvest.defineActionButton)) I get "function"
Sadly this game came out in 2007 and only supports Lua 5.1, so debug.getinfo does not give me nparams as I've read online that might have helped:
code:
local function onDebug()
harvest.print(_VERSION)
harvest.print(type(harvest.defineActionButton))
local temp = debug.getinfo(harvest.defineActionButton)
for key, value in pairs(temp) do
harvest.print("key: " .. tostring(key))
harvest.print("value: " .. tostring(value))
end
end
hook.add("textInput", onDebug)
Any tips on how I can get the number of parameters on this function and maybe their name? (I would assume that expected type is impossible)
I have also attempted solutions found in:
How to get name of the argument in lua?
lua - get the list of parameter names of a function, from outside the function
But I am unable to make those solutions working

If the function was written in Lua, you can dump and analyze its bytecode with string.dump(f), which should include parameter info. If it's a C function, that's not possible (aside from statically analyzing the binary itself, which is a different category of question).
If other attempts fail, you could try redefining the function with a fake one, like this...
--...
local defineActionButton_real = harvest.defineActionButton
harvest.defineActionButton = function(...)
print(...)
return defineActionButton_real(...)
end
...then observing the output when the game calls the fake function.

Related

Scan Lua file for invalid function names (World of Warcraft)

So I have a Wow addon which is many, many thousands of lines long. Sometimes, Blizzard removes Lua functions from the game and I'm not always sure whether the functions I've called in the addon are valid anymore.
Is there a way that I can scan an entire Lua file for functions that no longer exist?
I know that I can do something like this:
if not RemovedFunction then print("Function does not exist") end
But that requires me to check every function name one at a time so that's not realistic (there are hundreds).
I would like to be able to scan the entire Lua file and alert me if any function names that I've called are no longer present in World of Warcraft API.
The solution can be written in any language (does not have to be Lua script although that would be preferable).
You can find a changelog here
https://wow.gamepedia.com/Patch_9.0.1/API_changes
https://github.com/Ketho/BlizzardInterfaceResources/compare/8.3.7...9.0.1#diff-ca64e26bbd77a0dd7b6d3699c75cbf60dd7ac03e379b8085dd7efcca4a52510e
The GitHub project shows how those functions are scanned, it's essentially just scanning _G[] and Blizzard's FrameXML code
You can also upload a zip to Globe which will tell you about any removed API, e.g.
https://www.townlong-yak.com/globe/#h:2a8385bff94e98a6bad8f5f09b45a148-reads
A good API would list removed function names in their changelog. Just search your script for those names.
You can use a linter like luacheck to find undefined stuff in your script. This would require you to maintain a list of existing function names.
This also works for other globals.
Or you search your script for function calls and search that name in a list of existing function names. Or you check if this name is nil in your environment. A function call is any name that is followed by optional whitespace and either of (, " or {.
For functions this is trivial, for other variables it becomes a bit more complicated and you'll end up writing your own linter so you could as well just use an existing one.
Scan if the function name is nil
function isFunctionExist(functionName) --Function name in string
local func = load("return "..functionName")
if func == nil then
error("Invalid function name!") --There an invalid letter in your function name that cause load unable to load
end
return type(func()) == "function"
end
It also work on any lua interpreter not only in World of Warcraft addon
Lua will cause attempt to call nil value or similiar
So before run it we check whether is it nil or a function
load("return "..functionName) will return the functionName variable content even it nil then we check it with type if it an existent function it return "function"
type(func()) == "function" this line do the checking

Hacking Lua - Inject new functions into built Lua

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.
Sorry for not providing a full answer, but if you can provide a custom Lua VM and change the standard libraries, you should be able to to change the luaL_openlibs method in the Lua source to provide a table with my_hack() inside of it.
Since the Lua interpreter is usually statically compiled into the host executable, modifying the interpreter in some way will probably not be possible.
I think your best bet is to find some piece of Lua code which gets called by the host, and from that file use dofile to run your own code.

Lua table library removed?

I'm trying to learn the ropes on Lua, and I was going through the online tutorials. One problem I tried to solve was to examine a table local foo = {} to see how many elements it had. The tutorial gave the suggestion to use local length = table.getn(foo). When i try this using Lua52, I get an error stating attempt to call field 'getn' (a nil value). I looked around further and noticed that any of the functions given with table produce the same type of error. Was the table library removed from Lua? Is it a third-party library, or what gives?
Use the length operator # as in #foo.
table.getn was deprecated in 5.1 and removed in 5.2.
The table library wasn't removed, as it's an essential part of the language and the module system. The getn function was removed but if none of the table functions work, it's almost certainly because you've overwritten table.

Lua Sandboxing - Eliminating Function Creation

I've read on the Lua wiki / here / etc. on how to sandbox lua code generally. But I haven't been able to find something that disallows function creation. For example, the example here provides a sample code as:
assert(run [[function f(x) return x^2 end; t={2}; t[1]=f(t[1])]])
And that's with an empty environment. But I want to eliminate the ability to create a function (the 1st part of the code) - e.g., just allow expressions. Any idea on how to do that? Does it have to be in C somehow? Thanks in advance!
If you want to evaluate expressions only, you could try this:
function run(s) return loadstring("return "..s)() end
(error handling omitted)
This simple solution will prevent most `attacks', but not eliminate them because one can say
(function () f=function(x) print"hello" end end)()
which defines a new function named f.
Your best bet is to use a sandbox and not worry about what the user does to the environment, because it'll not be your environment.
You can try detecting the creation of functions by looking for the string "function" before allowing the execution of the lua script. For example from your C/C++ backend.
If "function" appears throw a "you are not allowed to create functions" error and don't execute the code.
A couple notes:
You might want to try to customize the detection a bit more - only throw errors if you detect function followed by blanks and an opening parenthesis, for example. I'm leaving that as an exercise.
You should be aware that there are some standard lua functions that kindof expect the users to be able to create functions - for example, the string table has several of those. Without creating functions, it'll be very difficult for your users to work with strings (it is already difficult enough with functions...)

Placeholder evaluation of lua code

I have an application that uses lua files for some of its more obscure configuration options. As such it mostly contains calls into the app to create things and alter properties; most C functions don't have a return value but some do.
I now have a need to read these same configuration files into a different application, and perform significantly different things when the functions are called (so I can't use common code). In addition, I'm only interested in a subset of the possible functions, and I think I can get away with by default ignoring (and/or returning nil) any other function call.
So I'm wondering what the best approach is here. How (from a C++ app), can I load and execute a lua script such that expressions etc are evaluated as normal but I can intercept and process certain app-defined C functions while simply ignoring (returning nil if required) calls to any other C functions?
(Note: I do have access to the vocabulary of the original app, which mostly uses luabind; I could just use the same definitions and change the implementation, but that's too fragile since the original app can have more functions added to it later. I would like something more generic.)
The goal is to get a bit of C code which I can use as a generic placeholder; the end result being "anything that's defined (standard library routines, functions defined in Lua, and C functions explicitly registered), call it as normal; for anything else, call one specific routine that simply does nothing, instead of raising an error". And preferably something compatible with luabind.
The whole process is initiated by a bit of C code that sets up the Lua environment, loads a set of files, calls one function, and then destroys the environment. There won't be anything ongoing.
Set a __call metamethod for nil:
debug.setmetatable(nil, { __call=function () end })
The _index metamethod for _G or other tables does not work because the name is resolved before the call.
(You don't need to use the debug API or library if you're setting this from C.)
How about using setfenv and a metatable? You can replace global environment table of certain function with an empty table. And then, set the placeholder function to ignore C-defined function.
local env = {} -- empty environment
local metatbl = {}
function metatbl.__index (tbl, key) -- provides placeholder function
return function()
print(key .. " called")
return(nil)
end
end
setmetatable(env, metatbl)
function samplefunc() -- your Lua code goes here
globalfunction "xyz" -- calls placeholder function
end
setfenv(samplefunc, env)
samplefunc()
If you want to use build-in function such as print, you can push it into env talbe like:
local env = {print = print}
If you have some way of differentiating the C functions from the ordinary Lua functions in your script, you can iterate over all functions defined in your Lua system, and for each C function that isn't on the list of functions you care about, replace that function's implementation with a simple nil-returning one. This is really easy if all the c-binding functions are defined tidily together in a table; if they're in _G you have a bit of a job ahead of you. The functions you do care about get bound via luabind as normal.

Resources