1

In the lua programming language, I know that you can lock the metatable of userdata with the metamethod __metatable so that no-one can view the userdata's metatable with the getmetatable() function. But, I still want to access that metatable after its been locked. So, my question is, after the userdata's metatable is locked, is it still possible (maybe through some backdoor) to still get the metatable of the locked userdata, or is it just not possible (if so, then for what reasons)?

EDIT #1: My motivation for wanting to know this is because I am trying to find a backdoor into Roblox's API so that I can more effectively script my games.

warspyking
  • 3,045
  • 4
  • 20
  • 37
Jack G
  • 4,553
  • 2
  • 41
  • 50

2 Answers2

3

This applies at least to lua 5.3

In lua you can use the debug library method debug.getmetatable. That should return the original metatable regardless of the __metatable metamethod. In C you can use the function lua_getmetatable for same purpose.

Also you could always make a variable somewhere to where you store the metatable and can access it later through that variable later.

Also if you used luaL_newmetatable, then you can still find the metatable in the registery with the metatable name you used.

Rochet2
  • 1,146
  • 1
  • 8
  • 13
2

You've stated you're using ROBLOX. When you think about it, they've locked this stuff for a reason. Why? Security purposes. Allowing scripters access to such things is dangerous and poses a serious threat. So the answer is no, once locked there is no way back into the metatable without a reference, because if there was the lock would be pointless.

ROBLOX also got rid of all functions in the debug library, but the recently added debug.traceback, so debug.getmetatable is definitely out of the question.

However, depending on your reasoning for this, there are others ways to accomplish the task. I'll go over some of them here:

1) If you want to set the metatable of an instance, make a fake instance using your own table, and then use __index and __newindex to control access to the object's properties and methods

2) If you want to set the metatable of a library, we follow the same approach as in 1, create a fake table and use __index to index the old table.

3) If you want to set the metatable of the global environment, set a new one with a pre-existing metatable. Make sure to use __index so the other variables still work!

As for simply reading the metatables, no you cannot do this.

In addition to that, if you lock your own tables, as mentioned earlier there is a way to access the metatable. Simply store a reference to it. The best way to do it would be make a local variable called meta in a do scope block.

I hope this answers your question, I tried to specifically target ROBLOX, since that's what your question was asking.

warspyking
  • 3,045
  • 4
  • 20
  • 37